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

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

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

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

xji 15.02.2019 19:11
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
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

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