Как правильно найти нужные значения из массива массивов в Ruby? - PullRequest
3 голосов
/ 09 октября 2011

У меня есть массив массивов в Ruby:

price_list = [
  ['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]
]

И мне нужно создать новый массив только с уникальными продуктами и минимальными ценами. Примерно так:

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

Какой самый быстрый и красивый способ сделать это в Ruby?

Ответы [ 4 ]

5 голосов
/ 09 октября 2011

Сгруппируйте по ключу (марка + модель) и получите минимальную цену для сгруппированных массивов:

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

Вывод:

[["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]]
1 голос
/ 09 октября 2011

Если вам не нужно сортировать по марке и модели, это можно сделать следующим образом:

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

Если вы хотите, чтобы он также сортировался, вам нужно снова отсортировать

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

Редактировать: uniq с блоком будет работать только в ruby ​​1.9

1 голос
/ 09 октября 2011
items = Hash.new()
price_list.each{|brand,model,price|
     item=items[brand+model]
     items[brand+model]=[brand,model,price] if (!item||item[2]>price)
}
0 голосов
/ 09 октября 2011

при использовании new_price_list = price_list & Array.new(price_list) должен возвращать новый массив со всеми элементами, уникальными для двух наборов в соответствии с api docs

Пересечение набора - возвращает новый массив, содержащий общие элементык двум массивам, без дубликатов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...