Я на самом деле думаю, что это отличный вопрос. Но во-первых, почему все не слишком обеспокоены этим? Вот производительность flatten
и flatten.compact
сравнению:
Here's the code I used to generate this chart, and one that includes memory.
Надеюсь, теперь вы видите, почему большинство людей не будут беспокоиться: это просто еще один постоянный фактор вы добавляете при составлении flatten
с compact
, может быть, это ценно, по крайней мере, теоретически сказать: как мы можем сэкономить время и пространство этой промежуточной структуры? Опять же, асимптотически не супер ценно, а любопытно думать.
Насколько я могу сказать, вы не можете сделать это, используя flatten
:
Прежде чем взглянуть на источник, я надеялся, что flatten
может принимать блок так:
[[3, [3, 3, 3]], [3, [3, 3, 3]], [3, [3, 3, 3]], nil].flatten {|e| e unless e.nil? }
Нет кости, хотя. Мы получаем это как возвращение:
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, nil]
Это странно, что она в основном подбрасывает блок прочь, как не-оп. Но это имеет смысл с source. Метод C flatten
, используемый в ядре Ruby, не параметризуется для принятия блока.
Процедура в исходном коде Ruby читает для меня нечто странное (я не программист на C), но в основном это делает что-то вроде глубинного поиска. Он использует стек, который добавляет каждый новый вложенный массив для обработки, с которой он сталкивается. (Он заканчивается, когда никто не остается.) Я не рассчитал это формально, но это приводит меня к угадыванию сложности наравне с DFS.
Таким образом, исходный код мог быть написан таким образом, что это могло бы работать, если бы была включена дополнительная настройка, если блок был передан. Но без этого вы застряли в небольшом ударе!
Несомненно, сделайте это самостоятельно, вручную. –
Да, есть * много * более эффективных способов, от качки собственного цикла до использования C++ вместо Ruby. Вопрос: почему вас это волнует? Это на самом деле какое-то узкое место? – meagar
Вы можете выполнить цикл вручную или получить ленивый перечислитель (если все методы, которые вы хотите использовать, находятся в 'Enumerable'). – ndn