解释 Ruby Array uniq 方法的一个表达式
c = %w(a b c d)
1.8.7 :025 > c.uniq {|x|x[/^a/]}
=> ["a", "b"]
1.8.7 :026 > c.uniq {|x|x[/^b/]}
=> ["a", "b"]
1.8.7 :027 > c.uniq {|x|x[/^c/]}
=> ["a", "c"]
1.8.7 :029 > c.uniq {|x|x =~ [/^c/]}
=> ["a"]
1.8.7 :030 > c.uniq {|s|s[/[^abc]/]}
=> ["a", "d"]
我理解正则表达式,但不明白 uniq 块是如何工作的。
c = %w(a b c d)
1.8.7 :025 > c.uniq {|x|x[/^a/]}
=> ["a", "b"]
1.8.7 :026 > c.uniq {|x|x[/^b/]}
=> ["a", "b"]
1.8.7 :027 > c.uniq {|x|x[/^c/]}
=> ["a", "c"]
1.8.7 :029 > c.uniq {|x|x =~ [/^c/]}
=> ["a"]
1.8.7 :030 > c.uniq {|s|s[/[^abc]/]}
=> ["a", "d"]
I understand the regular expression, I don't understand how does the uniq block work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这有点棘手。
该块中的 x 是数组中的每个值。您可以通过“字符串是否以
a
开头?”来定义唯一性。值a
是第一个评估为true
的值,因此是第一个值。b
是第一个评估为false
的值,第二个值也是如此。c
和d
也都计算为false
,但不是唯一的,因为已经找到了计算false
的值。这里同样如此。
a
是第一个 (false
),b
是第二个 (true
)。在这里,您可以看到
a
是第一个false
值,c
是第一个评估为true
的值,因此第二个独特的价值。在这里,您通过“字符串是否匹配正则表达式数组来定义唯一性,这些正则表达式确实匹配不以 c 开头的字符串”。诡异的!
这里您已经定义了一个字符类。您通过“包含 a、b 或 c 的字符串”定义了唯一性。
a
是第一个满足true
的条件。d
是唯一评估为false
的值。希望有帮助。
That's a bit of a tricky one.
The
x
in this block is every value in the array. You define uniqueness by "does the string start witha
?". Valuea
is the first to evaluate astrue
and is therefore the first value.b
is the first to evaluate asfalse
so is the second value. Bothc
andd
also evaluate asfalse
, but are not unique since a value that evaluatedfalse
was already found.The same holds here.
a
is the first (false
) andb
the second (true
).Here you see that
a
is the firstfalse
value andc
the first value to evaluate astrue
and therefore the second unique value.Here you have defined uniqueness by "does the string match an array of regular expressions that do match strings not starting with c". Weird!
Here you have defined a character class. You defined uniqueness by "strings containing a, b or c".
a
is the first to satisfy astrue
.d
is the only value to evaluate asfalse
.Hope that helps.
唯一性的确定基于将每个元素传递到块的结果。
例如,第一个表示询问每个元素是否是“a”。第一个说是,所以“a”被认为是唯一的。第二个说不,所以“b”被认为是唯一的。其他人也说“不”,因此它们不被认为是唯一的(因为我们已经看到了“不”的回答)。
然而,我无法轻易解释的是为什么这在 Ruby 1.8.7 中似乎对你有用;在 1.8.7 及之前版本中,Array#uniq 的块参数被忽略。该功能是在 Ruby 1.9 中添加的。也许你有补丁版本?
The determination of uniqueness is based on the result from passing each element to the block.
So, for example, the first one represents asking each element whether they are "a". The first one says yes, so "a" is considered unique. The second one says no, so "b" is considered unique. The others also say no, so they are not considered unique (since the response "no" is one we've already seen).
However, what I can't explain easily is why this appears to be working for you in Ruby 1.8.7; in 1.8.7 and prior a block argument to Array#uniq was ignored. This feature was added in Ruby 1.9. Perhaps you have a patched version?
这样看:当您将
uniq
与块一起使用时,您可以有效地构建一个数组数组,其中每个内部数组都是[result_of_block, array_element]
,然后查找唯一值在第一个元素中。因此,如果我们从: 开始,然后查看
数组的数组将如下所示:
在第一个元素中查找唯一值会产生
'a'
和nil
:并展开产生
['a', 'b']
。但不能保证您会得到'b'
作为第二个元素。您可以像这样编写自己的
uniq_by
:或这样:
Look at this way: when you use
uniq
with a block, you effectively build an array of arrays where each inner array is[result_of_block, array_element]
and then look for unique values in the first elements. So, if we start with:and look at
then the array of arrays would look this:
Looking for unique values amongst the first elements yields
'a'
andnil
:and unwrapping yields
['a', 'b']
. There's no guarantee that you'll get'b'
as the second element though.You can write your own
uniq_by
like this:or this: