Message Boards Message Boards

4 Replies
3 Total Likes
View groups...
Share this post:

How do I Split this?

I have different lists which, once joined and sorted, I'd like to split whenever an element from one of the lists appears again. For example:

r = {1, 3, 8}

s = {2, 7}

t = {0, 4, 5, 9}

Joined and sorted: {0, 1, 2, 3, 4, 5, 7, 8, 9}

The output I'm looking for is: {{0, 1, 2}, {3, 4}, {5, 7, 8}, {9}}

How can I do it?

POSTED BY: Fernando Benadon
4 Replies

Yes, I noticed that too when I tested it with the longer lists. I still appreciate it!

POSTED BY: Fernando Benadon
Posted 9 years ago

I deleted my previous answer as the function I wrote was not working properly in general (I guess I was lucky it worked with your values!).

POSTED BY: Xavier Roy

Thanks! I expanded it to five lists (r,s,t,u,v) and it works great.
Deleted my earlier question about recursion limit; figured out I can set $RecursionLimit to a higher value and it runs like a charm

POSTED BY: Fernando Benadon

It took me a while, but I think I understand what you're talking about.

What kind of a solution are you looking for? There are different kinds of solutions. This is how I would program it, using functional programming. This might be too mathy for some people's tastes:

First, we label each number with the list it came from. I want it to be in a certain format so that I can have a list of pairs where the first part of each pair is a list of labels and the last part of each list is the list of numbers that have those labels:

pairs = Union[Thread[{"r", r}], Thread[{"s", s}], Thread[{"t", t}]];
lst = SortBy[Last]@Map[List, pairs, {2}]

The result looks like this:

{{{"t"}, {0}}, {{"r"}, {1}}, {{"s"}, {2}}, {{"r"}, {3}}, {{"t"}, {4}}, {{"t"}, {5}}, {{"s"}, {7}}, {{"r"}, {8}}, {{"t"}, {9}}}

The idea is to turn that list into this list:

{{"t", "r", "s"}, {0, 1, 2}, {"r", "t"}, {3, 4}, {"t", "s", "r"}, {5, 7, 8}, {{"t"}, {9}}}

We have a list of labels and numbers. And each group of labels only has one of each label. I've written up a solution below and attempted to explain it. The solution is written very functionaly. This might be difficult for someone to use without background in this programming style

If the label of the second element occurs in the list of the labels of the first element, then we don't want to join them. Instead we recurse and run the function on the rest of the list, prepending the first element onto the results:

putTogether[{{l1_, n1_}, {{l2_}, {n2_}}, rest___}] /; MemberQ[l1, l2] := Prepend[putTogether[{{{l2}, {n2}}, rest}], {l1, n1}]

Otherwise (if the label of the second element isn't in the labels for the first element), we join them together and recurse:

putTogether[{{l1_, n1_}, {{l2_}, {n2_}}, rest___}] := putTogether[{{Append[l1, l2], Append[n1, n2]}, rest}]

Finally, if none of these patterns match, the function has completed and should just return what it has been given:

putTogether[else_] := else;

This function does the task requested:

Last /@ putTogether[lst]
{{0, 1, 2}, {3, 4}, {5, 7, 8}, {9}}
POSTED BY: Sean Clarke
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract