开发者

What is true way to find needed values from array of arrays in Ruby?

开发者 https://www.devze.com 2023-04-12 06:39 出处:网络
I have an array of arrays in Ruby: price_list =开发者_Go百科 [ [\'Brand-1\', \'Model-1\', 100.00],

I have an array of arrays in Ruby:

price_list =开发者_Go百科 [
  ['Brand-1', 'Model-1', 100.00],
  ['Brand-1', 'Model-2', 200.00],
  ['Brand-2', 'Model-1', 10.00],
  ['Brand-2', 'Model-2', 20.00],
  ['Brand-1', 'Model-1', 110.00],
  ['Brand-1', 'Model-2', 190.00],
  ['Brand-1', 'Model-3', 300.00],
  ...
  ['Brand-n', 'Model-n', 1234.00]
]

And I need to create new array with only unique products and minimal prices. Something like this:

new_price_list = [
  ['Brand-1', 'Model-1', 100.00],
  ['Brand-2', 'Model-1', 10.00],
  ['Brand-2', 'Model-2', 20.00],
  ['Brand-1', 'Model-2', 190.00],
  ['Brand-1', 'Model-3', 300.00],
  ...
  ['Brand-n', 'Model-n', 1234.00]
]

What is a fastest and most beautiful way to do this in Ruby?


Group by key (brand+model) and then get the minimum price on the grouped arrays:

prices = [
  ['Brand-1', 'Model-1', 100.00],
  ['Brand-1', 'Model-2', 200.00],
  ['Brand-2', 'Model-1', 10.00],
  ['Brand-2', 'Model-2', 20.00],
  ['Brand-1', 'Model-1', 110.00],
  ['Brand-1', 'Model-2', 190.00],
  ['Brand-1', 'Model-3', 300.00],
]

grouped = prices.group_by { |brand, model, price| [brand, model] }
grouped.values.map { |grouped_prices| grouped_prices.min_by(&:last) }

Output:

[["Brand-1", "Model-2", 190.0],
 ["Brand-1", "Model-3", 300.0],
 ["Brand-2", "Model-1", 10.0],
 ["Brand-2", "Model-2", 20.0],
 ["Brand-1", "Model-1", 100.0]]


items = Hash.new()
price_list.each{|brand,model,price|
     item=items[brand+model]
     items[brand+model]=[brand,model,price] if (!item||item[2]>price)
}


If you dont need to sort by brand and model, this can be done like this:

new_price_list = price_list.sort_by { |brand,model,price| price }.uniq {|brand, model, price| [brand, model] }

If you want it also sorted, you have to sort again

new_price_list = price_list.sort_by { |brand,model,price| brand + model }.sort_by { |brand,model,price| price }.uniq {|brand, model, price| [brand, model] }

Edit: uniq with block will work only in ruby 1.9


using new_price_list = price_list & Array.new(price_list) should return a new array with all elements unique to the two sets according to the api docs

Set Intersection—Returns a new array containing elements common to the two arrays, with no duplicates.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号