I'm for some reason hitting a wall here. I need help figuring this out please. I have the following type of 2D array:
不知什么原因,我撞到墙上了。我需要帮忙解决这个问题。我有以下类型的2D数组:
[["Bob", "Car", 25000],
["Bob", "TV", 5000],
["Bob", "dog", 1000],
["Sue", "Cat", 1000],
["Sue", "Car", 10000],
["Bob", "shoes", 100],
["Carol", "car", 20000]]
And I need to generate an array that is the sum of each of these people's total from the third element of each sub array. ie:
我需要生成一个数组它是每个子数组的第三个元素之和。即:
[["Bob", 31100],
["Sue", 11000],
["Carol", 20000]]
Right now I have a complicated and contrived solution using two loops that iterate through the entire array for each of its own elements. Is there an easier more streamlined way to do this? Especially since my data sets will be quite large. I know ruby has a bunch of awesome enumerables that seem like would fit here, but I can't quite think of how to fit them in.
现在我有了一个复杂的、经过设计的解决方案,它使用两个循环遍历整个数组中的每个元素。是否有一种更简单、更精简的方法来实现这一点?特别是我的数据集会很大。我知道ruby有很多很棒的可枚举类型,看起来很适合这里,但是我不知道如何将它们整合进来。
4 个解决方案
#1
1
arr = [["Bob", "Car", 25000],
["Bob", "TV", 5000],
["Bob", "dog", 1000],
["Sue", "Cat", 1000],
["Sue", "Car", 10000],
["Bob", "shoes", 100],
["Carol", "car", 20000]]
hash_result = Hash.new(0)
arr.each do |record|
hash_result[record[0]] += record[2]
end
This will give you a hash result. If you want an array, just call to_a
on hash_result
.
这会给你一个哈希结果。如果需要数组,只需在hash_result上调用to_a。
#2
4
You can use a counting hash:
您可以使用计数散列:
arr = [["Bob", "Car", 25000],
["Bob", "TV", 5000],
["Bob", "dog", 1000],
["Sue", "Cat", 1000],
["Sue", "Car", 10000],
["Bob", "shoes", 100],
["Carol", "car", 20000]]
arr.each_with_object(Hash.new(0)) { |(name,_,total),h| h[name] += total }
#=> {"Bob"=>31100, "Sue"=>11000, "Carol"=>20000}
Hash::new is used to create a hash with a default value of zero. That means that if the hash h
does not have a key name
, h[name]
returns zero. Since:
Hash:::new用于创建一个默认值为0的散列。这意味着如果哈希h没有键名,h[name]返回0。自:
h[name] += total
expands to:
扩展:
h[name] = h[name] + total
h[name]
on the right side of the equality returns zero when h
does not have a key name
.
等式右边的h[name]返回0,而h没有键名。
#3
1
You can iterate through the array of purchases and store the totals in a hash.
您可以遍历购买数组并将总数存储在散列中。
purchases = [
["Bob", "Car", 25000],
["Bob", "TV", 5000],
["Bob", "dog", 1000],
["Sue", "Cat", 1000],
["Sue", "Car", 10000],
["Bob", "shoes", 100],
["Carol", "car", 20000]
]
totals = Hash.new(0) # initialize the values to 0
purchases.each { |purchase|
totals[purchase[0]] += purchase[2]
}
#4
1
.group_by(&:first).map do |who, group|
[who, group.map(&:last).inject(:+)]
end
#1
1
arr = [["Bob", "Car", 25000],
["Bob", "TV", 5000],
["Bob", "dog", 1000],
["Sue", "Cat", 1000],
["Sue", "Car", 10000],
["Bob", "shoes", 100],
["Carol", "car", 20000]]
hash_result = Hash.new(0)
arr.each do |record|
hash_result[record[0]] += record[2]
end
This will give you a hash result. If you want an array, just call to_a
on hash_result
.
这会给你一个哈希结果。如果需要数组,只需在hash_result上调用to_a。
#2
4
You can use a counting hash:
您可以使用计数散列:
arr = [["Bob", "Car", 25000],
["Bob", "TV", 5000],
["Bob", "dog", 1000],
["Sue", "Cat", 1000],
["Sue", "Car", 10000],
["Bob", "shoes", 100],
["Carol", "car", 20000]]
arr.each_with_object(Hash.new(0)) { |(name,_,total),h| h[name] += total }
#=> {"Bob"=>31100, "Sue"=>11000, "Carol"=>20000}
Hash::new is used to create a hash with a default value of zero. That means that if the hash h
does not have a key name
, h[name]
returns zero. Since:
Hash:::new用于创建一个默认值为0的散列。这意味着如果哈希h没有键名,h[name]返回0。自:
h[name] += total
expands to:
扩展:
h[name] = h[name] + total
h[name]
on the right side of the equality returns zero when h
does not have a key name
.
等式右边的h[name]返回0,而h没有键名。
#3
1
You can iterate through the array of purchases and store the totals in a hash.
您可以遍历购买数组并将总数存储在散列中。
purchases = [
["Bob", "Car", 25000],
["Bob", "TV", 5000],
["Bob", "dog", 1000],
["Sue", "Cat", 1000],
["Sue", "Car", 10000],
["Bob", "shoes", 100],
["Carol", "car", 20000]
]
totals = Hash.new(0) # initialize the values to 0
purchases.each { |purchase|
totals[purchase[0]] += purchase[2]
}
#4
1
.group_by(&:first).map do |who, group|
[who, group.map(&:last).inject(:+)]
end