List 在列表的每n个索引处插入

List 在列表的每n个索引处插入,list,insert,elixir,element,List,Insert,Elixir,Element,是否有一个标准的Elixir函数可以在列表的每n个索引处插入一个元素 使用函数调用和返回,如: iex> List.insert_at_every([1,2,3,4,5], 2, Enum.random(["apple","banana"])) [1, 2, "apple", 3, 4, "apple", 5] 据我所知,这没有内置函数,但可以使用Enum.with_index和Enum.flat_map实现。当索引的其余部分和第二个参数是第二个参数减去1时,我们将元素+回调插入结果列表

是否有一个标准的Elixir函数可以在列表的每n个索引处插入一个元素

使用函数调用和返回,如:

iex> List.insert_at_every([1,2,3,4,5], 2, Enum.random(["apple","banana"]))
[1, 2, "apple", 3, 4, "apple", 5]

据我所知,这没有内置函数,但可以使用
Enum.with_index
Enum.flat_map
实现。当索引的其余部分和第二个参数是第二个参数减去1时,我们将元素+回调插入结果列表,否则只插入元素。我认为在示例列表中传递
1
作为each参数比传递
2
更有意义。如果需要,您可以使用
every-1
简单地更改
every

defmodule A do
  def insert_at_every(list, every, fun) do
    list
    |> Enum.with_index
    |> Enum.flat_map(fn {x, i} ->
      if rem(i, every) == every - 1 do
        [x, fun.()]
      else
        [x]
      end
    end)
  end
end

IO.inspect A.insert_at_every([1, 2, 3, 4, 5], 1, fn -> Enum.random(["apple", "banana"]) end)
IO.inspect A.insert_at_every([1, 2, 3, 4, 5], 2, fn -> Enum.random(["apple", "banana"]) end)
IO.inspect A.insert_at_every([1, 2, 3, 4, 5], 3, fn -> Enum.random(["apple", "banana"]) end)
输出:

[1, "apple", 2, "apple", 3, "banana", 4, "banana", 5, "apple"]
[1, 2, "apple", 3, 4, "apple", 5]
[1, 2, 3, "apple", 4, 5]

据我所知,这没有内置函数,但可以使用
Enum.with_index
Enum.flat_map
实现。当索引的其余部分和第二个参数是第二个参数减去1时,我们将元素+回调插入结果列表,否则只插入元素。我认为在示例列表中传递
1
作为each参数比传递
2
更有意义。如果需要,您可以使用
every-1
简单地更改
every

defmodule A do
  def insert_at_every(list, every, fun) do
    list
    |> Enum.with_index
    |> Enum.flat_map(fn {x, i} ->
      if rem(i, every) == every - 1 do
        [x, fun.()]
      else
        [x]
      end
    end)
  end
end

IO.inspect A.insert_at_every([1, 2, 3, 4, 5], 1, fn -> Enum.random(["apple", "banana"]) end)
IO.inspect A.insert_at_every([1, 2, 3, 4, 5], 2, fn -> Enum.random(["apple", "banana"]) end)
IO.inspect A.insert_at_every([1, 2, 3, 4, 5], 3, fn -> Enum.random(["apple", "banana"]) end)
输出:

[1, "apple", 2, "apple", 3, "banana", 4, "banana", 5, "apple"]
[1, 2, "apple", 3, 4, "apple", 5]
[1, 2, 3, "apple", 4, 5]

NB@Dogbert提出的解决方案当然更好,为了多样性,我发布这篇文章


要在列表中穿插一个常量值,可以使用and:

如果您想要使用函数来检索要在每次迭代中散布的元素,那么这将不起作用。在这种情况下,您需要自己实施穿插:

iex(2)> [1,2,3,4,5]
...(2)> |> Enum.chunk_every(2)
...(2)> |> Enum.map(& &1 ++ [Enum.random(~w|banana apple|)])
...(2)> |> List.flatten
#⇒ [1, 2, "banana", 3, 4, "apple", 5, "apple"]
上述结果始终包含一个冗余的尾部元素,之后应将其清除:

iex(3) > with [_ | result] <- :lists.reverse([1, 2, "banana", 3, 4, "apple", 5, "apple"]) do
...(3)>     :lists.reverse(result)
...(3)> end
#⇒ [1, 2, "banana", 3, 4, "banana", 5]
iex(3)>带[124;结果]:列表。反向(结果)
…(3)>结束
#⇒[1,2,“香蕉”,3,4,“香蕉”,5]

NB无论如何,@Dogbert提出的解决方案更好,为了多样性,我发布这篇文章


要在列表中穿插一个常量值,可以使用and:

如果您想要使用函数来检索要在每次迭代中散布的元素,那么这将不起作用。在这种情况下,您需要自己实施穿插:

iex(2)> [1,2,3,4,5]
...(2)> |> Enum.chunk_every(2)
...(2)> |> Enum.map(& &1 ++ [Enum.random(~w|banana apple|)])
...(2)> |> List.flatten
#⇒ [1, 2, "banana", 3, 4, "apple", 5, "apple"]
上述结果始终包含一个冗余的尾部元素,之后应将其清除:

iex(3) > with [_ | result] <- :lists.reverse([1, 2, "banana", 3, 4, "apple", 5, "apple"]) do
...(3)>     :lists.reverse(result)
...(3)> end
#⇒ [1, 2, "banana", 3, 4, "banana", 5]
iex(3)>带[124;结果]:列表。反向(结果)
…(3)>结束
#⇒[1,2,“香蕉”,3,4,“香蕉”,5]

谢谢,这是一个非常干净的解决方案。我认为这应该是
列表的一部分。谢谢,这是一个非常干净的解决方案。我认为这应该是
列表
的一部分。您的示例似乎不是每秒钟都插入一个元素。在1、2、3和4之后添加了一些内容,但在5之后没有添加任何内容。如果你在每一个元素后面插入,不是应该是
[1,2,“apple”,3,4,“apple”,5]
或者类似的东西吗?是的,这是正确的-我已经编辑了这个问题。你的示例似乎不是在每一个元素后面插入的。在1、2、3和4之后添加了一些内容,但在5之后没有添加任何内容。如果你在每一个元素后面插入,它不是
[1,2,“apple”,3,4,“apple”,5]
之类的吗?是的,这是正确的-我已经编辑了这个问题。