如何选择each
区块中的项目?或者,以相反的方式考虑它,如何修改select
块内的项目?
作为一个例子,给定一个整数数组,我如何拒绝奇数,返回偶数数组,同时加10?在以下示例中,我希望返回[12, 14, 16]
。
尝试select
:
a = (1..6).to_a
a.select! do |i|
if i % 2 == 0
a[a.find_index(i)] += 10 # This doesn't stick.
true # this works
end
end
p a # => [2, 4, 6]
尝试each
:
a = (1..6).to_a
a.each do |i|
if i % 2 == 0
a[a.find_index(i)] += 10
else
a.delete(a.find_index(i)) # I suppose this isn't working?
end
end
p a # => [1, 12, 3, 14, 5, 16]
答案 0 :(得分:2)
您可以使用select删除所有奇数,并使用map执行所需的其他操作:
a.select { |x| x % 2 == 0 }.map { |x| x + 10 }
=> [12, 14, 16]
答案 1 :(得分:1)
使用map!
转换数组的成员 - 而不是在数组中设置新值,只需返回您希望新值来自块的内容。对于您要拒绝的值,请返回nil
。
a = (1..6).to_a
a.map! do|i|
if i % 2 == 0
i + 10
end
end.compact!
p a # => [12, 14, 16]
由于多次传递的问题很多,这里有一个flat_map的单程解决方案:
a = (1..6).to_a
a = a.flat_map do|i|
if i.even? #happy?
[i + 10]
else
[]
end
end
p a # => [12, 14, 16]
可悲的是,没有flat_map!
所以我们必须重新分配a
。
答案 2 :(得分:1)
作为好奇心,你也可以在Ruby> = 2中使用Ruby的懒惰枚举。
mega_range = (1..100_000)
filtered_collection = mega_range.lazy.select do |n|
puts "selecting #{n}"
n.even?
end.map do |n|
puts "mapping #{n}"
n * 2
end
filtered_collection.take(10).to_a
# selecting 1
# selecting 2
# mapping 2
# selecting 3
# selecting 4
# mapping 4
# selecting 5
# selecting 6
# mapping 6
# selecting 7
# selecting 8
# mapping 8
# => [4, 8, 12, 16]
如您所见,select
和map
操作已合并,map
仅在所选事件上完成。
无需额外通过集合(这是compact!
所做的)。
答案 3 :(得分:1)
我认为仅使用select无法修改任何元素,无法实现目标。
以下是其他替代方案(可能与上面的一些答案重复):
ary = (1..6).to_a
ary.map! { |x| x.even? ? x + 10 : nil }.compact!
ary.keep_if { |x| x.even? }.map! { |x| x + 10 }
ary.delete_if { |x| x.odd? }.map! { |x| x + 10 }
ary = ary.inject([]) { |final, element| element.even? ? final.push(element + 10) : final }
p ary # => [12, 14, 16]
答案 4 :(得分:0)
试试这个:
>> (1..6).select(&:even?).map { |x| x + 10 }
=> [12, 14, 16]