Получение результата цикла .each с наименьшим числом от json - PullRequest
0 голосов
/ 25 июня 2019

У меня есть ответ API от API доставки, по которому я бы хотел автоматически выбрать самую низкую стоимость доставки по умолчанию.

Вот json:

[
  {"serviceName"=>"USPS First Class Mail - Letter", "serviceCode"=>"usps_first_class_mail", "shipmentCost"=>0.8, "otherCost"=>0.0},
  {"serviceName"=>"USPS First Class Mail - Large Envelope or Flat", "serviceCode"=>"usps_first_class_mail", "shipmentCost"=>1.3, "otherCost"=>0.0},
  {"serviceName"=>"USPS First Class Mail - Package", "serviceCode"=>"usps_first_class_mail", "shipmentCost"=>2.84, "otherCost"=>0.0},
  {"serviceName"=>"USPS Priority Mail - Package", "serviceCode"=>"usps_priority_mail", "shipmentCost"=>7.82, "otherCost"=>0.0},
  {"serviceName"=>"USPS Priority Mail - Medium Flat Rate Box", "serviceCode"=>"usps_priority_mail", "shipmentCost"=>12.8, "otherCost"=>0.0},
  {"serviceName"=>"USPS Priority Mail - Small Flat Rate Box", "serviceCode"=>"usps_priority_mail", "shipmentCost"=>7.5, "otherCost"=>0.0},
  {"serviceName"=>"USPS Priority Mail - Large Flat Rate Box", "serviceCode"=>"usps_priority_mail", "shipmentCost"=>17.6, "otherCost"=>0.0},
  {"serviceName"=>"USPS Priority Mail - Flat Rate Envelope", "serviceCode"=>"usps_priority_mail", "shipmentCost"=>6.95, "otherCost"=>0.0},
  {"serviceName"=>"USPS Priority Mail - Flat Rate Padded Envelope", "serviceCode"=>"usps_priority_mail", "shipmentCost"=>7.55, "otherCost"=>0.0},
  {"serviceName"=>"USPS Priority Mail - Regional Rate Box A", "serviceCode"=>"usps_priority_mail", "shipmentCost"=>9.95, "otherCost"=>0.0},
  {"serviceName"=>"USPS Priority Mail - Regional Rate Box B", "serviceCode"=>"usps_priority_mail", "shipmentCost"=>16.1, "otherCost"=>0.0},
  {"serviceName"=>"USPS Priority Mail - Legal Flat Rate Envelope", "serviceCode"=>"usps_priority_mail", "shipmentCost"=>7.25, "otherCost"=>0.0}
] 

Я бы тогда хотелчтобы определить самую низкую цену, которую затем следует передать платежному процессору.

Я пытался использовать <%= rate["shipmentCost"].min %>, но получил undefined method min 'для 0,8: Float` ... Какой 0,8 является самым низким вариантом, изjson response.

Каким образом я могу получить каждый цикл или цикл в целом, определить наименьший `rate [" shipmentCost "], а затем определить его, чтобы я мог использовать его для добавления к ценеgoods.

например, я хотел бы сделать что-то вроде:

rate_to_use = rate["shipmentCost"].min, а затем использовать «price + rate_to_use = total» для обработки платежа.Затем для доставки будет создана этикетка с тем же самым низким показателем или соответствует ей.

Ответы [ 2 ]

2 голосов
/ 25 июня 2019

Вы можете использовать Enumerable # min_by :

cheapest = @shipping_rates.min_by{|rate| rate['shipmentCost'] }
0 голосов
/ 25 июня 2019

Еще немного добавлю: если есть вероятность, что хеш JSON содержит значение nil или ключ не найден, ответ @ Vasfed (очень хороший) поднимет ArgumentError.

[1, nil].min_by(&:itself)
# => ArgumentError: comparison of NilClass with 1 failed

Поэтому я бы использовал:

@shipping_rates.min_by { |rate| rate['shipmentCost'] || Float::INFINITY }
# or
@shipping_rates.compact.min_by { |rate| rate['shipmentCost'] }

# e.g.
[1, nil].min_by { |x| x || Float::INFINITY }
# => 1
[1, nil].compact.min_by(&:itself)
# => 1

Таким образом вы избежите подобных ошибок.

Здесь есть одна оговорка с использованием Float::INFINITY: если у вас нет доступных shipmentCost, вам останется рендерить бесконечность. Поэтому вы можете захотеть обернуть это в проверку на равенство, чтобы избежать этого:

<% cheapest = @shipping_rates.min_by { |rate| rate['shipmentCost'] || Float::INFINITY }["shipmentCost"] %>
<%= cheapest unless cheapest == Float::INFINITY %>

Это заставляет меня думать, что вариант с compact - это путь :) Надеюсь, это поможет:

<%= @shipping_rates.compact.min_by { |rate| rate['shipmentCost'] %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...