Elixir: Add Enum.cons/3

Created on 5 Aug 2013  路  8Comments  路  Source: elixir-lang/elixir

I couldn't find anything like Ruby's Enumerable#cons method. Seems like it would be a good edition. Unfortunately I can't even figure how to implement it in Elixir.

Most helpful comment

Well I stumbled onto here looking for an Elixir version of each_cons. Turns out that Enum.chuck/3 does the trick too.

iex> Enum.chunk(list, 2, 1)
[[1, 2], [2, 3], [3, 4]]

All 8 comments

Could you describe what it does? I don't see it here

@alco he probably meant each_cons

@trans we add new functions to the api based on need. So if you feel like you are tackling an issue that would be nicely solved with each_cons, please let us know. Also, please take feature requests to the elixir-core mailing list, where you will be able to get feedback from other developers, thanks!

I know that this is an old issue but I was recently trying to solve a problem and each_cons in Elixir was just what I needed. It was a code golf challenge but I could see this type of thing cropping up in a real-world scenario.

The problem was:

Write a function lucky_sevens?(numbers), which takes in an array of integers and returns true if any three consecutive elements sum to 7.

In Ruby you could do something like [2,1,5,1,0].each_cons(3).any? { |arr| arr.reduce(:+) == 7 } which is very concise.

If we're not planning on adding this (or something similar) to the language how would one achieve a similar effect?

It's quite straightforward to define such a function for lists yourself:

defmodule MyList do
  def cons([], count), do: []
  def cons([_ | tail] = list, count), do: [Enum.take(list, count) | cons(tail, count)]
end

Doing this for any enumerable, shouldn鈥檛 be much more complicated. I'm not sure that a function that can be implemented in two lines has place in the standard library, given it's not used frequently.

With this you can solve your issue easily:

[2, 1, 5, 1, 0] 
|> MyList.cons(3) 
|> Enum.any?(fn list -> Enum.reduce(list, &Kernel.+/2) == 7 end)

Well I stumbled onto here looking for an Elixir version of each_cons. Turns out that Enum.chuck/3 does the trick too.

iex> Enum.chunk(list, 2, 1)
[[1, 2], [2, 3], [3, 4]]

That's perfect for me, though I don't see Enum.chunk/3 in the docs. Was it removed, or is it just not documented?

https://hexdocs.pm/elixir/Enum.html#chunk_by/2

@cheerfulstoic Enum.chunk/2/3/4 is deprecated in favor of Enum.chunk_every/2/3/4

https://github.com/elixir-lang/elixir/blob/master/CHANGELOG.md

For note, the replicate the example from the ruby doc page, it would be:

iex> Enum.chunk_every(1..10, 3, 1, :discard)
[
  [1, 2, 3],
  [2, 3, 4],
  [3, 4, 5],
  [4, 5, 6],
  [5, 6, 7],
  [6, 7, 8],
  '\a\b\t',
  '\b\t\n'
]

The last two are just lists in the printable range, so they are being shown as printed like a string, but they are still lists of numbers of the expected values (it's just the printer that is showing them different).

Was this page helpful?
0 / 5 - 0 ratings