结合多维数组的第一个元素
假设我有一系列产品ID和数量 ,如下所示:
records = [[1, 10], [1, 30], [4, 10], [4, 100], [5, 45]]
Ruby中最简单/最有效的方法是实现组合产品和数量的哈希,像这样?
products_needed = [{id: 1, count:40}, {id: 4, count: 110}, {id:5, count:45}]
试试这个:
records.group_by(&:first).map do |id, records_for_id| { id: id, count: records_for_id.sum(&:last) } end
如果您使用的是Ruby 2.4+,则可以使用group_by
然后使用transform_values
:
records.group_by(&:first) # => {1=>[[1, 10], [1, 30]], 4=>[[4, 10], [4, 100]], 5=>[[5, 45]]} records.group_by(&:first).transform_values do |values| values.sum(&:last) end # => {1=>40, 4=>110, 5=>45}
records .each_with_object(Hash.new(0)){|(k, v), h| h.merge!(k => v){|_, v1, v2| v1 + v2}} # => {1=>40, 4=>110, 5=>45} records .each_with_object(Hash.new(0)){|(k, v), h| h.merge!(k => v){|_, v1, v2| v1 + v2}} .map{|k, v| {id: k, count: v}} # => [{:id=>1, :count=>40}, {:id=>4, :count=>110}, {:id=>5, :count=>45}]
您没有产品ID和数量的数组。 你有一个整数数组的数组。 处理这个整数数组数组的最简单方法是不要有一个整数数组数组,而是一个Order
:
class Product def to_s; 'Some Product' end alias_method :inspect, :to_s end class OrderItem attr_reader :product, :count def initialize(product, count) self.product, self.count = product, count end def to_s; "#{count} x #{product}" end alias_method :inspect, :to_s private attr_writer :product, :count end class Order include Enumerable def initialize(*order_items) self.order_items = order_items end def each(&blk) order_items.each(&blk) end def items group_by(&:product).map {|product, order_items| OrderItem.new(product, order_items.sum(&:count)) } end def to_s; order_items.map(&:to_s).join(', ') end alias_method :inspect, :to_s private attr_accessor :order_items end
现在,假设您以Order
的forms接收数据,而不是整数数组的数组,如下所示:
product1 = Product.new product4 = Product.new product5 = Product.new order = Order.new( OrderItem.new(product1, 10), OrderItem.new(product1, 30), OrderItem.new(product4, 10), OrderItem.new(product4, 100), OrderItem.new(product5, 45) )
您需要做的就是:
order.items #=> [40 x Some Product, 110 x Some Product, 45 x Some Product]
底线是:Ruby是面向对象的语言,而不是面向整数数组的语言,如果使用富对象而不是整数数组的数组,您的问题将变得更加简单。
注意:我使用订单处理作为示例。 如果您的问题域是仓库管理或其他,则会有类似的解决方案。