Руби условную карту и замени

Я пытаюсь условно отобразить массив у меня есть:

Массив, который выглядит как [ "a", "b", "c" ]

Я хочу отобразить это в строке (используя карту!), Чтобы изменить все, что соответствует /b/ и изменить его на "bb". Это, кажется, не работает, хотя, кажется, не меняет массив.

Я хочу, чтобы это выглядело так [ "a", "bb", "c" ]

определить массив:

irb(main):001:0> a = [ "a", "b", "c" ]
=> ["a", "b", "c"]

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

irb(main):002:0> a.select { |e| e =~ /b/ }.map! { |e| e = "bb" }
=> ["bb"]
irb(main):003:0> p a.inspect
"[\"a\", \"b\", \"c\"]"

Поэтому я попытался сделать то же самое, но, назначив его новому массиву, он создает только массив с любыми измененными элементами - не то, что я хочу

irb(main):004:0> cc = a.select { |e| e =~ /b/ }.map! { |e| e = "bb" } 
=> ["bb"]
irb(main):005:0> p cc.inspect
"[\"bb\"]"
=> nil

Что мне здесь не хватает? Мне здесь не хватает фундаментальных знаний по Ruby.

2 ответа

Ты звонишь select на a, который возвращает новый экземпляр Array, на котором на следующем шаге вы звоните map!, изменяя этот новый экземпляр (не оригинальный). Чтобы добиться того, что вы хотите, вы можете сделать:

a.map! { |e| e =~ /b/ ? 'bb' : e }

Правильная логика выглядит так:

results = a.map { |e| if e =~ /b/ then "bb" else e end }

Та же логика с использованием троичного оператора:

results = a.map { |e| e =~ /b/ ? "bb" : e }

Если вам действительно нужно сделать замену на месте, используйте ! как это:

a.map! { |e| e =~ /b/ ? "bb" : e }

Вот почему ваш код в вашем посте работает не так, как вы ожидаете:

  • Ваш select возвращает новый массив, то map! модифицирует новый массив. Это одна проблема.

  • Что еще более важно, select Метод не работает так, как вы его используете. select Метод возвращает только те элементы, которые соответствуют.

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

Другие вопросы по тегам