我有一个<code>map</code>,它要么更改值,要么将其设置为nil。然后我想从列表中删除nil条目。该列表不需要保存。
这是我目前拥有的:
# A simple example function, which returns a value or nil
def transform(n)
rand > 0.5 ? n * 10 : nil }
end
items.map! { |x| transform(x) } # [1, 2, 3, 4, 5] => [10, nil, 30, 40, nil]
items.reject! { |x| x.nil? } # [10, nil, 30, 40, nil] => [10, 30, 40]
我知道我可以做一个循环,并有条件地在另一个数组中收集,如下所示:
new_items = []
items.each do |x|
x = transform(x)
new_items.append(x) unless x.nil?
end
items = new_items
但这似乎不是那么惯用。有没有一种很好的方法可以在列表上映射函数,随时删除/排除 nils?
红宝石 2.7
现在有了!
Ruby 2.7正是为了这个目的引入了< code>filter_map。它是习惯性的和表演性的,我希望它很快成为规范。
例如:
numbers = [1, 2, 5, 8, 10, 13]
enum.filter_map { |i| i * 2 if i.even? }
# => [4, 16, 20]
在这种情况下,当块求值为false时,只需:
items.filter_map { |x| process_x url }
“Ruby 2.7添加了Enumerable#filter_map”是一篇很好的文章,针对解决这个问题的一些早期方法提供了一些性能基准:
N = 100_000
enum = 1.upto(1_000)
Benchmark.bmbm do |x|
x.report("select + map") { N.times { enum.select { |i| i.even? }.map{ |i| i + 1 } } }
x.report("map + compact") { N.times { enum.map { |i| i + 1 if i.even? }.compact } }
x.report("filter_map") { N.times { enum.filter_map { |i| i + 1 if i.even? } } }
end
# Rehearsal -------------------------------------------------
# select + map 8.569651 0.051319 8.620970 ( 8.632449)
# map + compact 7.392666 0.133964 7.526630 ( 7.538013)
# filter_map 6.923772 0.022314 6.946086 ( 6.956135)
# --------------------------------------- total: 23.093686sec
#
# user system total real
# select + map 8.550637 0.033190 8.583827 ( 8.597627)
# map + compact 7.263667 0.131180 7.394847 ( 7.405570)
# filter_map 6.761388 0.018223 6.779611 ( 6.790559)
尝试使用减少
或注入
。
[1, 2, 3].reduce([]) { |memo, i|
if i % 2 == 0
memo << i
end
memo
}
我同意大家公认的答案,我们不应该< code>map和< code>compact,但原因不一样。
我觉得在那个
地图的深处,那么紧凑
相当于选择
然后地图
。考虑一下:地图
是一个一对一的功能。如果要从一组值进行映射,并且进行了映射
,则需要在输出集中为输入集中的每个值提供一个值。如果您必须事先选择
,那么您可能不希望在片场使用地图
。如果你必须在之后选择
(或压缩
),那么你可能不希望在片场有地图
。无论哪种情况,您都会在整个集合上迭代两次,而归约
只需要一次。
此外,在英语中,您正在尝试“将一组整数减少为一组偶数整数”。
您可以使用< code>compact:
[1, nil, 3, nil, nil].compact
=> [1, 3]
我想提醒大家,如果您得到一个数组,其中包含nils作为<code>map</code>块的输出,并且该块试图有条件地返回值,那么您就有代码气味,需要重新思考您的逻辑。
例如,如果你正在做这样的事情:
[1,2,3].map{ |i|
if i % 2 == 0
i
end
}
# => [nil, 2, nil]
那就不要。相反,在< code >映射之前,< code >拒绝您不想要的东西或< code >选择您想要的东西:
[1,2,3].select{ |i| i % 2 == 0 }.map{ |i|
i
}
# => [2]
我考虑使用<code>compact</code>来清理一个烂摊子,这是为了摆脱我们没有正确处理的事情,通常是因为我们不知道会发生什么。我们应该始终知道在我们的程序中丢弃了什么样的数据;意外/未知数据不正确。每当我在研究的数组中看到nil时,我都会深入研究它们存在的原因,看看是否可以改进生成数组的代码,而不是让Ruby浪费时间和内存生成nil,然后在数组中筛选以稍后删除它们。
'Just my $%0.2f.' % [2.to_f/100]
只有当每个键在map1中都有唯一的值时,我才会陷入如何将键值对从map1转移到map2的困境。 假设我有以下地图: 地图1:[1,2][2,4][4,4] 我想算法应该是: 遍历第一张地图中的条目。 向map2添加密钥。 将一个值添加到检查map2的值的集合 如果值是重复的,则不会将该值添加到集合中,并且忽略将其相应的键添加到map2。 代码片段: 我的想法是如何在正确的轨道上完成的吗?这里迷失了
我在团队项目中的tfs中有一个项目,然后我们将该项目移动到另一个团队项目中不同的位置。 我已将Jenkins配置为连接到团队项目并生成我的解决方案,但当我更改设置以连接到新的tfs团队项目时,它显示以下错误: 所以上面显示有一个现有的工作区,所以我运行下面的命令来删除它 它提示工作区已被删除,但我仍然收到同样的错误。 我还通过运行以下命令检查了映射是否已被删除: 但它表示工作空间并不像预期的那样存
问题内容: 我有一条路线映射为: 如何在运行时删除/重新映射此路由到空处理程序? 问题答案: 这将删除中间件和/或(获取/发布)路由。在express@4.9.5上测试 请注意,它 要求 中间件/路由功能具有 名称 : 如果该函数是匿名的, 它将不起作用 :
自从我将我的项目从jhipster 5.8.2升级到jhipster 6.5.1以来,我对Mapper有很多警告。 我会正确处理此警告,不会在所有映射器中添加此属性: 例如,我有以下错误: 在我的对象权限中,我有: 以及以下许可: 和映射器: 带有“忽略=true”的ligne不起作用。 你有什么想法吗?
我这里有一个奇怪的问题,如果我错了,请原谅我。 我这里的问题是,我在应用程序中为两个实体定义了一个manytone映射。删除时,我想忽略删除其他实体。 假设Emp到Dept有多个关系,我正在通过会话删除Emp记录。删除(EmpId),此时我不想删除与Emp实体关联的部门。 我不能在hbm中改变级联选项。 这种情况类似于 “如果有10个emp属于部门编号101,并且在删除任何一个emp时,它也将尝试
如何在不删除索引映射的情况下从elasticsearch数据库中删除数据? 我是Tire gem,使用删除命令删除我所有的映射并再次运行创建命令。我想避免创建命令一次又一次地运行。 请帮我解决这个问题。