6
$\begingroup$

Let's say I have the following list:

list = 
  {{"Text", "hello", "a"}, {"Text", " world", "a"}, {"TextElement", "line", "a"}, 
   {"TextElement", "line", "a"}, {"Text", "!", "b"}, {"Text", "ok", "c"}}

I want to to combine elements in list with the same first and last item (Eg: "Text" and "a"), but I do not want to combine elements which meet some condition. For this example, I do not want to combine elements whose first item is "TextElement". Thus, here is the expected output:

{{{"Text", "hello", "a"}, {"Text", " world", "a"}}, 
 {{"TextElement", "line", "a"}}, 
 {{"TextElement", "line", "a"}}, 
 {{"Text", "!", "b"}}, 
 {{"Text", "ok", "c"}}}

Outline (for readability): {1, 2, 3, 4, 5, 6}{{1, 2}, {3}, {4}, {5}, {6}}

I've tried the following code:

SplitBy[list, First[#] && Last[#] && ! (#[[1]] == "TextElement" && #[[2]] == "line") &]

It seemed to work at first, but fails the test above, as it combines the two "TextElement" elements. After looking at how the test function is evaluated, I can see why it doesn't work. How do I elegantly achieve the output above without resorting to loops?

$\endgroup$
2
  • $\begingroup$ Are they always sorted so that the elements you want to combine are next to each other? $\endgroup$ – Carl Woll Dec 17 '19 at 21:57
  • $\begingroup$ Thanks, yes. Otherwise Gather or GatherBy would be more appropriate. $\endgroup$ – user55405 Dec 23 '19 at 18:11
5
$\begingroup$

I think Split might be easier to use here:

Split[
  list, 
  First[#1] == First[#2] && Last[#1] == Last[#2] && First[#1] != "TextElement" &
]

(* Out: 
{
  {{"Text", "hello", "a"}, {"Text", " world", "a"}},
  {{"TextElement", "line", "a"}}, 
  {{"TextElement", "line", "a"}}, 
  {{"Text", "!", "b"}},
  {{"Text", "ok", "c"}}
}
*)
$\endgroup$
4
$\begingroup$

Other formulations:

Split[list, #[[{1, -1}]] == #2[[{1, -1}]] && #[[1]] != "TextElement" &]

SplitBy[list, {#[[1]] /. "TextElement" :> Unique[], #[[-1]]} &]

Related: How to Gather a list with some elements considered unique

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy