У меня есть списокКак я могу перечислить список в эликсире?
[1, 4, 3]
Я хочу, чтобы умножить его, что-то вроде:
[1, 4, 3] * 3 # => [1, 4, 3, 1, 4, 3, 1, 4, 3]
Как я могу это сделать?
У меня есть списокКак я могу перечислить список в эликсире?
[1, 4, 3]
Я хочу, чтобы умножить его, что-то вроде:
[1, 4, 3] * 3 # => [1, 4, 3, 1, 4, 3, 1, 4, 3]
Как я могу это сделать?
Я считаю, идиоматическое решение Elixir будет использовать List.duplicate/2
list |> List.duplicate(3) |> List.flatten
Обратите внимание, что если ожидается, что в list
есть вложенные списки, и они не должны быть уплощен, следует использовать:
list |> List.duplicate(3) |> :lists.concat
- кредиты идут на @Dogbert
Если вы просто замените 'List.flatten' на': lists.concat', вы получите самое быстрое решение в этом потоке (контрольный показатель в моем ответе). +1 для 'List.duplicate/2'. – Dogbert
@ Dogbert Честно говоря, это «самый быстрый» в пределах стандартного интервала отклонений :) Я оставил бы этот ответ неповрежденным для формулировки «идиоматический». В «нашем» ответе я бы пошел с ': lists.concat (: lists.duplicate (@list, 100)) ', чтобы сохранить его, скажем, в одном синтаксисе. – mudasobwa
Да, скорость в значительной степени идентична моей лучшей, но 'List.duplicate', безусловно, более идиоматична, чем' Enum.map' здесь. – Dogbert
Простейшая вещь, которая приходит на ум:
def multiply_list(list, factor) do
Enum.reduce(1..factor, [], fn(_, acc) -> acC++ list end)
end
А как насчет моего ответа? – radubogdan
Я хотел бы использовать Stream.cycle/1
iex> stream = Stream.cycle([1, 4, 3])
iex> Enum.take(stream, 9)
[1, 4, 3, 1, 4, 3, 1, 4, 3]
Я хотел бы использовать Enum.map
с :lists.concat
(Enum.concat
гораздо медленнее, чем :lists.concat
):
:lists.concat(Enum.map(1..100, fn(_) -> @list end))
некоторые ориентиры для предложений в этой теме, и некоторые из моих попыток:
defmodule BasicBench do
use Benchfella
@list Enum.to_list(1..100)
bench "1 by @asiniy" do
Enum.reduce(1..100, [], fn(_, acc) -> acC++ @list end)
end
bench "2 by @radubogdan" do
Enum.take(Stream.cycle(@list), 10000)
end
bench "3 by @Dogbert" do
Enum.flat_map(1..100, fn(_) -> @list end)
end
bench "4 by @Dogbert" do
Enum.concat(Enum.map(1..100, fn(_) -> @list end))
end
bench "5 by @Dogbert" do
:lists.concat(Enum.map(1..100, fn(_) -> @list end))
end
bench "6 by @mudasobwa" do
@list |> List.duplicate(100) |> List.flatten
end
bench "7 by @mudasobwa + @Dogbert" do
:lists.concat(List.duplicate(@list, 100))
end
end
Выход:
benchmark name iterations average time
7 by @mudasobwa + @Dogbert 50000 35.72 µs/op
5 by @Dogbert 50000 38.92 µs/op
6 by @mudasobwa 10000 124.30 µs/op
3 by @Dogbert 10000 174.63 µs/op
4 by @Dogbert 10000 242.24 µs/op
2 by @radubogdan 2000 924.04 µs/op
1 by @asiniy 1000 2143.24 µs/op
Пожалуйста upvote ответ на Dogbert, то есть) быстрее, и б) приносит намного больше значения, чем моя глупая ссылка на документации. – mudasobwa