В Ruby что делает array.select {| x | array.count (x)> 1} значит в словах? - PullRequest
0 голосов
/ 09 апреля 2020

Что означает array.count(x) в следующем:

arr1 = [1, 1, 3, 2, 6, 7, 9 ,6, 5, 1, 8, 9, 3]

def dups (array)
  duplicates = array.select { |x| array.count(x) > 1} #the (x) 
  duplicates.uniq
end

p dups(arr1) => [1,3,6,9]

Результат - то, что я хочу, но мне трудно понять, когда я говорю, что делает блок кода. Я поэкспериментировал с кодом и удалил (x), чтобы убедиться, что тогда я просто получаю все уникальные числа в массиве один раз, но не могу пройти через часть array.count(x) > 1.

Ответы [ 2 ]

2 голосов
/ 09 апреля 2020

select - метод фильтрации. Он передает каждый элемент в блок, и блок определяет, должен ли этот элемент быть включен в вывод, возвращая true или false.

Блок в вашем коде делает это, подсчитывая, как часто этот элемент происходит в массиве. Если это происходит более одного раза, блок возвращает true, а select включает в вывод соответствующий элемент.

Это может помочь поставить счетчик x, x и Возвращаемое значение блока в таблице:

 x | count(x) | count(x) > 1
---+----------+-------------
 1 | 3        | true
 1 | 3        | true
 3 | 2        | true
 2 | 1        | false
 6 | 2        | true
 7 | 1        | false
 9 | 2        | true
 6 | 2        | true
 5 | 1        | false
 1 | 3        | true
 8 | 1        | false
 9 | 2        | true
 3 | 2        | true

Ваш select возвращает все элементы с count выше 1: (с true в последнем столбце)

array = [1, 1, 3, 2, 6, 7, 9, 6, 5, 1, 8, 9, 3]
array.select { |x| array.count(x) > 1 }
#=> [1, 1, 3, 6, 9, 6, 1, 9, 3]

uniq затем избавляется от дубликатов:

array.select { |x| array.count(x) > 1 }.uniq
#=> [1, 3, 6, 9]

Вы могли заметить, что count должен пройти array один раз для каждого элемента, чтобы подсчитать его вхождения.

Гораздо быстрее использовать ha sh для подсчета элементов:

counts = Hash.new(0)
array.each { |x| hash[x] += 1 }
counts
#=> {1=>3, 3=>2, 2=>1, 6=>2, 7=>1, 9=>2, 5=>1, 8=>1}

Подсчет вхождений настолько распространен, что Ruby 2.7 имеет специальный метод tally:

counts = array.tally
#=> {1=>3, 3=>2, 2=>1, 6=>2, 7=>1, 9=>2, 5=>1, 8=>1}

Теперь мы можем просто выбрать ключи со значением выше 1:

counts.select { |k, v| v > 1 }
#=> {1=>3, 3=>2, 6=>2, 9=>2}

counts.select { |k, v| v > 1 }.keys
#=> [1, 3, 6, 9]
1 голос
/ 09 апреля 2020

TL; DR

Код использует Array # select для возврата элементов, которые имеют более одного совпадения в вашем объекте Array на основе Array # count больше чем 1. Ниже описано, как #select и #count взаимодействуют, чтобы это произошло.

Анализ и объяснение

array.select { |x| array.count(x) > 1}

Array # select здесь важен, потому что он говорит:

Для каждого элемента array , вернуть этот элемент если следующий блок оценивается как верный

Когда элемент, переданный в блок, имеет более одного совпадения в массиве, этот элемент возвращается. Если в массиве есть только одно совпадение (нулевое совпадение не имеет смысла в вашем примере), то этот элемент возвращается , а не .

На простом языке блок означает:

Для каждого элемента массива , временно сохраненного в переменной области действия x , используйте метод Array # count , чтобы получить количество подходящих элементов в массив, который больше 1. Код предполагает, что переменная, хранящаяся в x , может сравниваться с целым числом (в данном случае значением 1).

Короче говоря, #select отображает элементы на блок, блок оценивает количество совпадений, используя #count, и затем элементы, которые имеют несколько совпадений, возвращаются как новый объект Array.

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