#arrays #ruby #loops #iteration #idioms
#массивы #ruby #циклы #итерация #идиомы
Вопрос:
У меня есть 2 массива
asc = [0, 1, 2, 3, 4, 5]
dsc = [5, 4, 3, 2, 1, 0]
Мне нужен новый массив, который является результатом умножения каждого соответствующего элемента в asc и dsc
Я привык к Clojure, где я бы просто map
(map #(* %1 %2) asc dsc) ;=> (0 4 6 6 4 0)
Является ли их эквивалентом в Ruby, каким был бы идиоматический способ сделать это в Ruby?
Я новичок в Ruby, но, похоже, у него действительно хорошие лаконичные решения, поэтому я предполагаю, что я что-то упускаю.
Я просто пишу:
i = 0
res = []
while i < asc.length() do
res.append(asc[i] * dsc[i])
end
Комментарии:
1. Вы забыли запятые в
asc
иdsc
.
Ответ №1:
Используйте zip, чтобы объединить каждый элемент с соответствующим ему массивом из двух элементов, а затем сопоставить
asc.zip(dsc).map { |a, b| a * b }
=> [0, 4, 6, 6, 4, 0]
Ответ №2:
Похоже, что dsc
(«по убыванию») является производным от asc
(«по возрастанию»), и в этом случае вы могли бы написать:
asc.each_index.map { |i| asc[i] * asc[-i-1] }
#=> [0, 4, 6, 6, 4, 0]
Вы также можете написать:
[asc, dsc].transpose.map { |a,d| a*d }
#=> [0, 4, 6, 6, 4, 0]
или:
require 'matrix'
Matrix[asc].hadamard_product(Matrix[dsc]).to_a.first
#=> [0, 4, 6, 6, 4, 0]
См. Matrix#hadamard_product .
Ответ №3:
Используйте map
и with_index
:
asc = [0, 1, 2, 3, 4, 5]
dsc = [5, 4, 3, 2, 1, 0]
res = asc.map.with_index{ |el, i| el * dsc[i] }
puts res.inspect
# [0, 4, 6, 6, 4, 0]
В качестве альтернативы можно использовать each_index
и map
:
res = asc.each_index.map{ |i| asc[i] * dsc[i] }
Комментарии:
1. Я думаю
zip
, что это будет использоваться чаще, но у него есть недостаток, по сравнению с вашим ответом, в создании временного массива (asc.zip(dsc)
). Вы могли бы вместо этого написать этоasc.each_index.map { |i| asc[i] * dsc[i] }
(хотя я не думаю, что это предпочтительнее).2. @CarySwoveland Спасибо, что предложили другое решение! Я добавил это в свой ответ.
3. @CarySwoveland еще один способ избежать временного массива
asc.enum_for(:zip, dsc)
Ответ №4:
Вы также можете написать, как показано ниже:
asc = [0, 1, 2, 3, 4, 5]
dsc = [5, 4, 3, 2, 1, 0]
p asc.zip(dsc).collect{|z| z.inject(:*)}
[0, 4, 6, 6, 4, 0]