【问题标题】:find duplicates in Ruby array of arrays, sum their values, then combine them在 Ruby 数组数组中查找重复项,对它们的值求和,然后将它们组合起来
【发布时间】:2016-10-11 14:47:14
【问题描述】:

我有一个管道分隔的文本文件,我正在循环浏览它,如下所示:

123|ADAM JOHNSON|AAUA|||||||||||1||||
123||AAUA||||||||8675|90.0|90.0||||||||
444|STEVE SMITH|AAUA|||||||||||1|||||
444||AAUA||||||||2364|50.0|50.0|||||||
444||AAUA||||||||8453|50.0|50.0||||
567|ALLEN JONES|AAUA|||||||||||1||||||
567||AAUA||||||||6578|75.0|75.0||||||
567||AAUA||||||||1234|10.0|10.0||||
567||AAUA||||||||1234|15.0|15.0|||||

我首先获取这些行的第一个、第十个和第十一个索引,并将它们放入一个数组数组中,如下所示:

CSV.foreach('data.txt', { :col_sep => '|' }) do |row|
  if row[1].nil?
    @group_array << [row[0], [row[10], row[11]]]
  end
end

所以我得到类似的东西:

[["123", ["8675", "90.0"]]
------------------
["444", ["2364", "50.0"]]
["444", ["8453", "50.0"]]
------------------
["567", ["6578", "75.0"]]
["567", ["1234", "10.0"]]
["567", ["1234", "15.0"]]]

我正在苦苦挣扎的是遍历数组,找到具有相同第一个索引(3 个整数 id)的分组,循环遍历然后在第二个数组中找到具有相同 4 个整数 id 的任何重复项,然后添加第三个index 浮动然后吐出一个最终数组,其中删除了重复项并将它们的值相加。

预期输出应如下所示:

[["0006310001", ["789663473", "90.0"]],
["0006410001", ["297103188", "50.0"]],
["0006410001", ["757854164", "50.0"]],
["0006610001", ["557493572", "75.0"]],
["0006610001", ["981894386", "25.0"]]]

【问题讨论】:

  • 是的,需要澄清,但您应该在发布问题之前做到这一点。
  • 另外,发布您的预期输出。
  • 你说得对,这不是借口,但这是一项正在进行的工作,我正在严重旋转我的车轮。 @SteveTurczyn 已经提供了解决问题的答案。

标签: arrays ruby


【解决方案1】:

根据创建方式,我认为您的数据项看起来不像 [["123", ["8675", "90.0"]]]...更像是 ["123", ["8675", "90.0"]]

在这种情况下,这应该做你想要的......

group_array = @group_array.sort
result = []
save_3 = nil
save_4 = nil
total = 0.0
group_array.each do |group|
  if group[0] != save_3 || group[1][0] != save_4
    result << [save_3, [save_4, total.to_s]] if save_3
    total = 0.0
    save_3 = group[0]
    save_4 = group[1][0]
  end
  total += group[1][1].to_f
end
result << [save_3, [save_4, total.to_s]] if save_3

【讨论】:

  • 你说得对,我不会在一个数组中包含一个数组数组,我将更改我上面的帖子。当我在单独循环遍历 csv 文件时将 @group_array 放入主数组时就是这种情况。我认为像上面那样采用批处理路线可能会更好。
  • 可以在您进行初始构建时完成。您确定 CSV 已排序吗?你不会有(例如)["567", ["1234", "15.0"]], ["567", ["6578", "75.0"]],["567", ["1234", "10.0"]] 如果它们有问题,我们可以插入,但如果它们有问题,它会运行得更快。
  • CSV 最初没有排序,没有。我将有您刚刚给出的示例,其中第二个数组的第一个索引将出现故障,它们可能位于组内的任何位置。这个过程是否能够很好地扩展?假设我有一个包含数千行的 csv..
  • 好的,我已经发布了另一个可以处理无序数据并且具有更好可扩展性的答案。
【解决方案2】:

好的,应该可以更好地扩展一些东西......

group_hash = Hash.new(0.0)
CSV.foreach('data.txt', { :col_sep => '|' }) do |row|
  if row[1].nil?
    group_hash[ [row[0], row[10]] ] += row[11].to_f
  end
end
# produces a hash with key [a, b] value sum_of_c
# if you need an array of [a, [b,c]] then next step is...
@group_array = group_hash.to_a.map{|entry| [entry[0][0], [entry[0][1], entry[1]]]}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-27
    • 2019-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    相关资源
    最近更新 更多