Удалить последний элемент из списка в эликсире?

Как бы вы просто убрали 20 из конца этого примера?

[46, 238, 64, 30, 105, 136, 98, 75, 23, 157, 11, 20]

Самый простой способ записать это на самом деле - Enum.drop(list, -1). Хотя это не обязательно может быть самым быстрым.

xji 15.02.2019 19:11
5
1
4 509
4

Ответы 4

Вы могли сделать:

List.pop_at(x, -1)
{20, [46, 238, 64, 30, 105, 136, 98, 75, 23, 157, 11]}

самое быстрое решение, которое я знаю, с one
от @ mudasobwa решение 1
:

x |> Enum.reverse() |> tl() |> Enum.reverse()

Некоторые другие решения:
решение 2:

[k] = Enum.chunk(x, length(x)-1)

решение 3:

List.delete_at(x, length(x)-1)

решение 4:

x |> List.to_tuple() |> Tuple.delete_at(length(x)-1) |> Tuple.to_list

Еще более интересный вопрос: как это сделать быстрее всего? давайте протестируем это!

Я получил следующий результат, используя Бенчи, каждое решение было вычислено 50000 раз, и я использовал список, созданный с помощью Enum.to_list(1..10_000)

Name                                  ips        average  deviation         median         99th %
mudasobwa's solution              14.80 K       67.57 μs    ±34.17%          79 μs          91 μs
solution 1                        14.79 K       67.59 μs    ±33.96%          79 μs          91 μs
solution 4                        10.71 K       93.38 μs    ±32.67%          81 μs         201 μs
Roman Rabinovich's solution        8.45 K      118.33 μs    ±18.27%         118 μs         171 μs
OneSneakyMofo's solution           5.07 K      197.34 μs    ±13.60%         193 μs         331 μs
dawner's solution                  4.57 K      219.00 μs    ±11.87%         216 μs      256.23 μs
solution 3                         3.41 K      292.91 μs    ±20.01%         290 μs      506.64 μs
solution 2                         0.83 K     1205.52 μs    ±22.25%        1105 μs     2061.77 μs

Comparison: 
mudasobwa's solution              14.80 K
solution 1                        14.79 K - 1.00x slower
solution 4                        10.71 K - 1.38x slower
Roman Rabinovich's solution        8.45 K - 1.75x slower
OneSneakyMofo's solution           5.07 K - 2.92x slower
dawner's solution                  4.57 K - 3.24x slower
solution 3                         3.41 K - 4.33x slower
solution 2                         0.83 K - 17.84x slower

Отлично. Можете ли вы сравнить мой?

OneSneakyMofo 14.09.2018 05:20

Следуйте руководству по стилю кода: начинайте конвейер с термина, а не с функции: x |> Enum.reverse() |> tl() |> Enum.reverse() (и используйте круглые скобки в вызовах функций).

Aleksei Matiushkin 14.09.2018 06:03

Кстати, спасибо @mudasobwa, ссылки на эти 2 стиля кодирования: github.com/christopheradams/…github.com/christopheradams/…

Nathan Ripert 14.09.2018 10:16

@OneSneakyMofo, обновил отчет о тестовом стенде. Я добавил ваше решение, так как оно отвечает на вопрос.

Nathan Ripert 14.09.2018 10:29

почему бы не erlangs {NewList, _} = lists: split (List, (length (List) -1))

Roman Rabinovich 16.09.2018 05:00

@Roman Rabinovich, я обновил тестовый стенд вашим решением. В эликсире это записывается так: {k, _} = :lists.split((length(x)-1), x) x - это список, а k - список за вычетом последнего элемента. (Боюсь, вы перепутали arg1 и arg2 в своем решении)

Nathan Ripert 17.09.2018 13:33

Так много способов сделать это. Вот еще один:

[46, 238, 64, 30, 105, 136, 98, 75, 23, 157, 11, 20]
|> Enum.reject(&(&1 == 20)

Это удалит все вхождения 20, а не «20 из конца этого примера», как указано в OP.

Aleksei Matiushkin 14.09.2018 06:09

Да, я в курсе, но я ответил на вопрос. Он хочет «просто удалить 20 из конца этого примера», что он и делает.

OneSneakyMofo 14.09.2018 06:17

Хотя решение, данное Натаном Рипером, достаточно хорошее, оно не совсем быстрое.

Enum.reverse/1 - это функция общего назначения, которая проходит через reduce.

Чистый erlang :lists.reverse/1 должен быть быстрее (совсем немного):

x |> :lists.reverse(x) |> tl() |> :lists.reverse()

Он хотел получить ответ от Эликсира, а не от Эрланга.

OneSneakyMofo 14.09.2018 06:18

@OneSneakyMofo Это Эликсир. В Erlang нет каналов.

Aleksei Matiushkin 14.09.2018 06:18

@mudasobwa на самом деле, во время первого вычисления ваше решение было немного быстрее, и теперь, когда я его повторно запускаю, оно немного медленнее ... так как разница довольно мала, ее нельзя надежно измерить на испытательном стенде.

Nathan Ripert 14.09.2018 12:18

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