У файлі NEWS написано:
* Array
* new method:
* Array#keep_if
* Array#repeated_combination
* Array#repeated_permutation
* Array#rotate
* Array#rotate!
* Array#select!
* Array#sort_by!
* extended methods:
* Array#{uniq,uniq!,product} can take a block.
...
* Enumerable
* New methods:
* Enumerable#chunk
* Enumerable#collect_concat
* Enumerable#each_entry
* Enumerable#flat_map
* Enumerable#slice_before
У цій статті коротко розглянемо ці методи.select! та keep_if
ary.select! {|item| block }
Метод select! вибирає тільки ті елементи масиву ary для яких значення в середині блоку block рівне true. Він є аналогічним новому методу keep_if з однією різницею: select! повертає nil якщо ніяких змін не було зроблено. keep_if завжди повертає об’єкт.> (1..10).select {|i| i % 3 == 0 } #=> [3, 6, 9]
=> [3, 6, 9]
Більше комбінацій і перестановок.Ruby 1.9 вніс корисні методи поєднання(Array#combination) і перестановки(Array#permutation). Тепер також існують Array#repeated_combination і Array#repeated_permutation:
> [1, 2, 3].combination(2).to_a
=> [[1, 2], [1, 3], [2, 3]]
> [1, 2, 3].repeated_combination(2).to_a
=> [[1, 1], [1, 2], [1, 3], [2, 2], [2, 3], [3, 3]]
> [1, 2, 3].permutation(2).to_a
=> [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
> [1, 2, 3].repeated_permutation(2).to_a
=> [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
rotate / rotate!
Цей метод видаляє перший елемент і додає його до початку. Можна передати ціле число, скільки кроків він повинен "крутити" (можливе і негативне значення).
> [1, 2, 3, 4, 5].rotate
=> [2, 3, 4, 5, 1]
> [1, 2, 3, 4, 5].rotate(2)
=> [3, 4, 5, 1, 2]
> [1, 2, 3, 4, 5].rotate(-2)
=> [4, 5, 1, 2, 3]
Невеликі зміни: sort_by, uniq / uniq!, product
Ці методи тепер можуть приймати блок.
- sort_by (блок визначає, як повинен бути сортований масив). Крім того доступний новий метод предикат sort_by!
> %w{ apple pear fig }.sort_by {|word| word.length} => ["fig", "pear", "apple"]
- product (повертає масив з усіх комбінації елементів усіх масивів) тепер також приймає блок, який обробляє кожен результат, а не повертає його
> [1,2,3].product([4,5]) => [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]] > [1,2].product([3,4],[5,6]) => [[1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4, 5], [2, 4, 6]]
- uniq (видаляє дублікати) тепер може приймати блок.
> c = [ "a:def", "a:xyz", "b:abc", "b:xyz", "c:jkl" ] > c.uniq => ["a:def", "a:xyz", "b:abc", "b:xyz", "c:jkl"] > c.uniq{|s| s[/^\w+/]} => ["a:def", "b:abc", "c:jkl"]
flat_map та його аліас collect_concat
Цей метод працює як map, але якщо якийсь елемент також є Enumerable, блок виконується і для кожного з його дочірніх елементів (але не рекурсивно).
> [[1,2],[3,[4,5]]].flat_map{|i|i}
=> [1, 2, 3, [4, 5]]
each_entry
Аналогічний методу each, але може задовольняти кілька аргументів, як єдиний масив.
chunk(англ. - шматок)
Ще один дуже цікавий , але трохи дивний у використанні метод. Він розбиває себе на кілька Enumerator-ів (шматків), використовуючи правило, задане у блоці. Воно тримає разом ті частини, що "відповідають" в серіях. На виході маємо результат фільтру і Enumerator послідовних елементів. Для ясності поглянемо на ці приклади.
> (1..42).chunk{|n| n%11 == 0}.each{|result, elements|
puts "#{result}: #{elements*', '}"
}
false: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
true: 11
false: 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
true: 22
false: 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
true: 33
false: 34, 35, 36, 37, 38, 39, 40, 41, 42
=> nil
> a=(0..4).map{[]}
=> [[], [], [], [], []]
> (1..42).chunk{|n| n%5}.each{|remainder, elements| a[remainder] += elements}
=> nil
> puts a
[[5, 10, 15, 20, 25, 30, 35, 40], [1, 6, 11, 16, 21, 26, 31, 36, 41], [2, 7, 12, 17, 22, 27, 32, 37, 42], [3, 8, 13, 18, 23, 28, 33, 38], [4, 9, 14, 19, 24, 29, 34, 39]]
Блок chunk також може повертати спеціальні значення: символи, які починаються з підкреслення. В даний час підтримуються два спеціальних символа:
- :_separator (або nil) - елемент відкинуто
- :_alone - елемент завжди отримує один шматок(chunk)
slice_before
Цей метод також дозволяє розділити Enumerable. Необхідно вказати шаблон / блок, який повинен відповідати / бути правдою, і це розділить до цього елементу:
> %w|Ruby is 2 parts Perl, 1 part Python, and 1 part Smalltalk|.slice_before(/\d/).to_a
=> [["Ruby", "is"], ["2", "parts", "Perl,"], ["1", "part", "Python,", "and"], ["1", "part", "Smalltalk"]]
Цікаво спостерігати, в якому напрямку рухається Ruby з цими методам. Деякі з них, це всього лиш раніше зниклі (наприклад, select!). Тим не менш, інші, як на мене, мають обмежене коло використання (chunk). Це лише моя особиста думка. Можливо я і помиляюся ;)
Це запис був підготовлений по мотивах http://rbjl.net/27-new-array-and-enumerable-methods-in-ruby-1-9-2-keep_if-chunk
Немає коментарів:
Дописати коментар