Сортировка объектов в хэш типов - PullRequest
0 голосов
/ 04 июля 2018

Я бы хотел пройтись по массиву объектов и отсортировать их в хэш типов продуктов.

Результат, который я ищу, примерно такой.

{ "Bike" => [line_item, line_item, line_item], "Car" => [line_item] }

Пока у меня есть следующее

PRODUCT_TYPES = Hash.new []

Input.cart.line_items.each do |item| 
  PRODUCT_TYPES[item.variant.product.product_type] << line_item
end

Как правильно достичь этого?

Редактировать:

Это мой ввод:

[#<LineItem:0x7f5994288da0 @grams=0, @original_line_price=#<Money:0x7f5994289220>, @discounts=[], 
 @properties_was={}, @line_price=#<Money:0x7f5994289370>, @variant=#<Variant:0x7f59942898b0>, @properties={}, 
 @adjustments=[], @quantity=1, @source_indices={"12593518772283:86c53a47791a6f36173f4ecc3039ec9b"=>1}, 
 @line_price_was=#<Money:0x7f5994289370>>]

1 Ответ

0 голосов
/ 04 июля 2018

Простейшим подходом будет использование group_by:

Input.cart.line_items.group_by { |item| item.variant.product.product_type }

Это должно возвращать хеш точно так, как нужно - вывод оцененного блока возвращается как ключ хеша (т. Е. item.variant.product.product_type), с элементами, назначенными в качестве массива значений для этих ключей.

Примечание: если вы запрашиваете несколько записей, связанных с line_item, стоит including, чтобы избежать проблем с N + 1, например.

Input.cart.line_items.includes(variant: { product: :product_type }).group_by do |item| 
  item.variant.product.product_type
end

Вот еще один простой способ добиться того, чего вы добились после использования each_with_object:

Input.cart.line_items.each_with_object(Hash.new { |h, k| h[k] = [] }) do |item, hash| 
  hash[item.variant.product.product_type] << item
end

Редактировать: только что понял, что ваш вопрос помечен как Ruby, а не Rails. В этом случае each_with_object недоступен, хотя вы можете добиться аналогичного результата, используя reduce:

Input.cart.line_items.reduce(Hash.new { |h, k| h[k] = [] }) do |hash, item| 
  hash.tap { |h| h[item.variant.product.product_type] << item }
end

Обратите внимание на использование tap: reduce возвращает все, что оценивает блок, а не объект и присваивает первому аргументу блока (в данном случае hash). Использование tap гарантирует, что это всегда хеш.


С точки зрения того, что является «правильным», group_by существует именно для этой цели - использование этого даст читабельный подход, оптимизированный для выполняемой задачи.

Надеюсь, это поможет - дайте мне знать, как вы поживаете, и если у вас есть какие-либо вопросы:)

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