Ivanori

Ivanori

Algorithm for splitting a list into N sublists

On a page there’re 3 columns. And I have a list of objects. Every object should go one of the 3 columns in the subsequent order.

1 -> 1, 2 -> 2, 3 -> 3, 4 -> 1, 5 -> 2 and so on.

I’m trying to come up with an algorithm and have difficult to do so.

What’s the best way to do so? A high-level pointer will be fine.

update:

of put that simply: split a list into N sub-lists. The 1st sub-list might be bigger than the rest.

If I have 7 elements and I want to split them into N = 3 sub-lists, there should be created 3 sublists:

[[3 elements], [2 elements], [2 elements]] 

Namely, I want to preserve all the elements. Enum.chunk_every(…, :discard) won’t work.

Most Liked

kokolegorille

kokolegorille

You might use Enum.chunk_every/2 on a collection.

iex> 1..10 |> Enum.chunk_every(3) |> IO.inspect(charlists: :as_list)
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

You could also use remainder like this

iex> for x <- 1..10, do: rem x, 3
[1, 2, 0, 1, 2, 0, 1, 2, 0, 1]
michalmuskala

michalmuskala

def split(list), do: split(list, [], [], [])

defp split([x1, x2, x3 | rest], l1, l2, l3), 
  do: split(rest, [x1 | l1], [x2 | l2], [x3 | l3])
defp split([], l1, l2, l3), 
  do: {Enum.reverse(l1), Enum.reverse(l2), Enum.reverse(l3)}
defp split([x1, x2], l1, l2, l3), 
  do: {Enum.reverse(l1, [x1]), Enum.reverse(l2, [x2]), Enum.reverse(l3)}
defp split([x1], l1, l2, l3), 
  do: {Enum.reverse(l1, [x1]), Enum.reverse(l2), Enum.reverse(l3)}
iex> Test.split(Enum.to_list(1..10))
{[1, 4, 7, 10], [2, 5, 8], [3, 6, 9]}

If your list has always length divisible by 3, you don’t need the last 2 clauses which account for uneven split.

jfeng

jfeng

If you don’t care about the order in which they’re put in the bins, this should work. Definitely suboptimal because of the list length and integer division at each step, though.

def chunker(list, parts), do: do_chunk(list, parts, [])

defp do_chunk(_, 0, chunks), do: chunks

defp do_chunk(to_chunk, parts, chunks) do
  chunk_length = to_chunk |> length() |> div(parts)
  {chunk, rest} = Enum.split(to_chunk, chunk_length)
  do_chunk(rest, parts - 1, [chunk | chunks])
end

iex> chunker([1, 2, 3, 4, 5, 6, 7], 4)
[[6, 7], [4, 5], [2, 3], [1]]
iex> chunker([1, 2, 3, 4, 5, 6, 7, 3)
[[5, 6, 7], [3, 4], [1, 2]]
iex> chunker([1, 2, 3, 4, 5, 6, 7, 10)
['\a', [6], [5], [4], [3], [2], [1], [], [], []]
LostKobrakai

LostKobrakai

I‘d do it like this:

columns = 
  list
  |> Enum.with_index()
  |> Enum.map(fn {_, i} -> rem(i, 3) end)

Enum.zip(list, columns)

Where Next?

Popular in Questions Top

gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
Codball
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; someth...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New

We're in Beta

About us Mission Statement