合并多维数组的第一个元素

时间:2017-08-23 17:40:21

标签: ruby-on-rails ruby

假设我有一系列产品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}]

4 个答案:

答案 0 :(得分:4)

试试这个:

records.group_by(&:first).map do |id, records_for_id|
  {
     id: id,
     count: records_for_id.sum(&:last)
  }
end

答案 1 :(得分:3)

如果您使用的是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}

答案 2 :(得分:1)

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}]

答案 3 :(得分:0)

拥有一系列产品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的形式接收数据,而不是整数数组,如下所示:

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是一种面向对象的语言,而不是面向整数数组的语言,如果你使用富对象而不是整数数组的数组,你的问题会变得简单得多

注意:我使用订单处理作为示例。如果您的问题域是仓库管理或其他,则会有类似的解决方案。