Динамическое разрушение аргументов блока Ruby - PullRequest
1 голос
/ 12 августа 2011

Недавняя хорошая статья о деструктуризации рубина определяет деструктурирование как способность связывать набор переменных с соответствующим набором значений в любом месте, где вы обычно можете связать значение с одной переменной, и дает пример деструктуризация блока

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

triples.each { |(first, second, third)| puts second } =>#[2, 5, 8]

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

triples = [[1, 2, 3], [4, 5, 6], [7, 8, 9],...,[]]

а мы бы хотели получить элементы первой записи для каждого подмассива?

triples.each { |(first, second, third,...,n)| puts first }

Каков наилучший способ создания локальных переменных (first, second, third,...,n) динамически?

Ответы [ 2 ]

5 голосов
/ 12 августа 2011

В вашем конкретном случае вы бы использовали сплат для сбора всего, кроме первого значения:

triples.each { |first, *rest| puts first }
#-----------------------^splat

Запись *rest просто собирает все, что осталось, в массив под названием rest.

В общем, нет большого смысла в создании произвольного числа локальных переменных (second, third, ..., nth), потому что вы не сможете ничего с ними сделать; Вы могли бы, вероятно, подстегнуть больной беспорядок злых ушей, но у нас уже есть прекрасный и функциональный класс Array, так зачем беспокоиться?

2 голосов
/ 12 августа 2011

, если это массив массивов:

triples = [[1, 2, 3], [4, 5, 6], [7, 8, 9],...,[]]

и мы хотим перебрать тройки, тогда это сработает, потому что внутренние массивы имеют только 3 элемента.

triples.each { |first, second, third| puts first }

Или вы хотели напечатать?

new_triples = [[1, 2, 3,...,n], [4, 5, 6,...,n], [7, 8, 9,...,n],...,[]]

в этом случае я бы воспользовался предложением 'mu' выше

new_triples.each { |first, *rest| puts first }

Надеюсь, я уловил ваше намерение, извините, в противном случае.

...