I have a list of elements -

bigList = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};

And two sublists:

sublistOne = {"H", "B", "D"};
sublistTwo = {"I", "L", "J"};

How do I efficiently create a function f that returns TRUE only if all elements of sublistOne come before all elements of sublistTwo in bigList?

For the provided example, f should return TRUE. However, if we kept the same sublistOne and set sublistTwo = {"I", "F", J"}, f should return false because element F in sublistTwo appears prior to element H in sublistOne.

Please note that I could scramble the English alphabet in bigList and then have the first example return FALSE. The function f should only test the index of each variable and ignore its numeric or string value.


You could use Position to extract the positions of the elements in bigList. Then, you only need to ensure that the biggest position number in the sublistOne is smaller than the smallest position number in sublistTwo

f[big_, s1_, s2_] := Max[#1] < Min[#2] & @@ (Position[big, Alternatives[##]] & @@@ {s1, s2})

Another way:

And @@ MapThread[
  Cases[bigList, Alternatives[##], 1, 1] =!= {#2} &,
  {sublistOne, sublistTwo}]

As a function, which bails out at the first unordered pair:

ordQ[ordering_, list1_, list2_] := Catch[
   If[Cases[ordering, Alternatives[##], 1, 1] === {#2}, 
     Throw[False]] &,
   {list1, list2}];

ordQ[bigList, sublistOne, sublistTwo]
(* True *)

Using two new-in-Version-10 variations:


(* True *)

Operator form of Position:

pF2=With[{p=Position[Alternatives@@#]&/@{#1,#2}},   Max[p[[1]]@#3]<Min[p[[2]]@#3]]&;
(* True *)

Your Answer

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