.select / .first ruby​​方法 - 实际发生了什么?

时间:2013-11-18 20:07:00

标签: ruby

我有以下代码行:

name_array = ["Business", "Business", "Business"]
date_array = ["12/1/10", "1/1/11", "2/1/11"]
score_array = ["40","67","46"]

array = name_array.zip(date_array, score_array).select { |x| x.first == 'Business' }

上面的代码行实际上是做什么的?我不明白x.first片段加上设置它等于一个字符串 - 我认为它返回了数组的第一个值/值?

2 个答案:

答案 0 :(得分:1)

首先要理解的是Array#zip在这里做了什么。

# The .zip() call on its own:
name_array.zip(date_array, score_array)
# Returns a 2D array
# [["Business", "12/1/10", "40"], ["Business", "1/1/11", "67"], ["Business", "2/1/11", "46"]] 

.zip的结果是三个子数组,其中第一个元素是来自name_array的值。

然后Array#select应用于该二维数组。 .select以块为参数。如果该块返回true,则返回数组值。

因此,它返回任何子数组(因为它在2D数组上迭代),其第一个元素是'Business'。在你的情况下,那是所有。当然,Array#first返回每个子数组的第一个元素,然后将其与字符串(== 'Business')

进行比较
# Calling .select on the literal array returned by .zip()
[
  ["Business", "12/1/10", "40"],
  ["Business", "1/1/11", "67"],
  ["Business", "2/1/11", "46"]
].select { |x| x.first == 'Business' }

# The result is the same as the input, since all of them match 'Business'
# [["Business", "12/1/10", "40"], ["Business", "1/1/11", "67"], ["Business", "2/1/11", "46"]]

将其中某些值更改为'Business'以外的值,.select不会返回它们。

[
  ["Business", "12/1/10", "40"],
  ["Something", "1/1/11", "67"],
  ["Else", "2/1/11", "46"]
].select { |x| x.first == 'Business' }
# [["Business", "12/1/10", "40"]]

答案 1 :(得分:1)

上面的代码行可以分成几个部分。

# Combine arrays elementwise
zipped_array = name_array.zip(date_array, score_array)
# => [["Business", "12/1/10", "40"], ["Business", "1/1/11", "67"], ["Business", "2/1/11", "46"]]

# Select all items where the first element is "Business"
zipped_array.select { |x| x.first == "Business" }

这是差异

Array#first

  

返回数组的第一个元素或前n个元素。如果数组为空,则第一个表单返回nil,第二个表单返回一个空数组。另请参阅#last以获得相反的效果。

示例:

[1, 2, 3, 4, 5].first { |x| x > 3 }
# => 4

zipped_array.first { |x| x.first == "Business" }
# => ["Business", "12/1/10", "40"]

Array#select

  

返回一个新数组,其中包含给定块返回true值的所有ary元素。

示例:

[1, 2, 3, 4, 5].select { |x| x > 3 }
# => [4, 5]

zipped_array.select { |x| x.first == "Business" }
# => [["Business", "12/1/10", "40"], ["Business", "1/1/11", "67"], ["Business", "2/1/11", "46"]] 

修改

专门回答关于x.first的问题。没有任何块的Array#first返回数组中的第一项。还有Array#last

示例:

[1, 2, 3, 4, 5].first
# => 1

[1, 2, 3, 4, 5].last
# => 5