Почему uniq возвращает исходное значение массива после отображения в Ruby? - PullRequest
1 голос
/ 19 марта 2019

Я попробовал следующий код:

numbers = [1,2,2,3,4]
numbers.map.uniq {|number| number < 2 }

Насколько я понимаю, возвращаемое значение map передается uniq.Я ожидал:

[true, false]

Вместо этого я получил:

[1, 2]

Похоже, что uniq поддерживает ссылку на исходный массив.

Может ли кто-нибудь предоставить информациюв это поведение?

Ответы [ 3 ]

5 голосов
/ 19 марта 2019

Array#uniq принимает блок, определяющий условие на то, что должно быть обработано uniq.

main > numbers = [1,2,2,3,4].map
#⇒ #<Enumerator: ...>
main > numbers.uniq
#⇒ [1, 2, 3, 4]

# effectively the same as
main > numbers.to_a.uniq
#⇒ [1, 2, 3, 4]

main > numbers.uniq { |number| number.odd? }
#⇒ [1, 2]

Последний возвращает один нечетный и одиннечетный (четный) элемент.В вашем случае он возвращает 1 элемент, который меньше 2, и один элемент, который больше или равен двум.


Обратите внимание, что перечислитель map действительно существует:

numbers.each &Math.method(:sqrt)
#⇒ [1.0, 1.4142135623730951, 1.4142135623730951,
#        1.7320508075688772, 2.0]
3 голосов
/ 19 марта 2019

На самом деле вы ничего не делаете с вызовом карты, ваша функция примерно эквивалентна этой:

[1,2,2,3,4].uniq {|number| p number < 2 }

Методы типа map возвращают тип Enumerable, и вы затем вызываете uniq на этом Enumerable.Из документов Ruby :

Если блок не указан, вместо него возвращается Enumerator.

По сути, ваша карта не используется.

Я думаю, вы также неправильно понимаете метод uniq.Uniq собирается отфильтровать любые элементы из массива, которые не являются уникальными (например, [1, 1, 2, 3, 3, 4, 5].uniq == [1, 2, 3, 4, 5]), а не возвращать, является ли элемент уникальным (истина или ложь) в массиве.

0 голосов
/ 19 марта 2019
numbers.uniq.map { |number| number < 2 }


уникальный метод

uniq → new_ary щелкните, чтобы переключить источник uniq {| item | ...} → new_ary Возвращает новый массив, удаляя повторяющиеся значения в self.

Если указан блок, он будет использовать возвращаемое значение блока для сравнение. Он сравнивает значения, используя их хэш и EQL? методы для эффективности. Я пересекается по порядку, и первое вхождение сохраняется.

a = ["a", "a", "b", "b", "c"]

a.uniq # => ["a", "b", "c"]

b = [["студент", "Сэм"], ["студент", "джордж"], ["учитель", "мац"]]

b.uniq {| s | s.first} # => [["student", "sam"], ["teacher", "matz"]]

Подробнее о методе uniq можно прочитать здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...