Переопределение элементов массива в «каждом» цикле

#ruby #overriding #each

#ruby #переопределение #каждый

Вопрос:

 a = [1, 2, 3]
a.each do |x| x =10 end
  

После этой операции массив a остается неизменным [1, 2, 3] . Как преобразовать это в [11, 12, 13] ?

Ответ №1:

Используйте collect! метод:

 a = [1, 2, 3]
a.collect!{ |x| x   10 }
  

Комментарии:

1. map! на 4 знака короче! 😀

Ответ №2:

Существует два основных класса решений:

Императивный код, изменяющий объект

 a.map! { |x| x   10 }
  

Почти функциональное решение

 a = a.map { |x| x   10 }
  

Оба метода имеют свое место.

Комментарии:

1. Первый задан dmarkow, а второй задан Ryanmt.

2. Я определенно опоздал, и это действительно не очень хороший пример разделения императивного и функционального, но я попытался добавить некоторую ценность. Я никогда не отвечаю на вопросы разумными ответами, но иногда я начинаю с вопроса без ответа и меня прерывают или я работаю слишком медленно, это точно.

3. Вам неудобно использовать a как для исходного, так и для нового массива?

4. Хех, да, «полуфункциональный».

Ответ №3:

Мне самому нравится псевдонимное имя «map». В нем меньше символов.

Разница с этими методами по сравнению с тем, что вы сделали, в два раза. Во-первых, вы должны использовать метод, который изменяет исходный массив (обычно это методы bang или методы, имя которых заканчивается на ! (сопоставить!, собрать!, …) Во-вторых, a.each — это метод, обычно используемый для простого просмотра массива для использования отдельных элементов. Методы Map или Collect возвращают массив, содержащий возврат из каждой итерации блока.

Следовательно, вы могли бы сделать следующее:

 a = [1,2,3]
b = []
a.each do |x| 
   b << x 10
end
  

или вы могли бы использовать метод map или collect, как продемонстрировано dmarko, или как здесь:

 a = [1,2,3]
a = a.map {|x| x 10}