How to rearrange sublists based upon the element in the first position?
Move D to the front, leaving the order of the rest unchanged:
lis1 /. {a___String, "D", b___String} :> {"D", a, b}
{{{"D", "J", "W", "L"}, {"D", "Q", "R", "T"}, {"D", "O", "P",
"W"}, {"D", "Z", "L", "M"}}}
Swap the first element and D:
lis1 /. {a_String, b___String, "D", c___String} :> {"D", b, a, c}
{{{"D", "J", "W", "L"}, {"D", "R", "T", "Q"}, {"D", "P", "O",
"W"}, {"D", "Z", "L", "M"}}}
If there is a D in every list or if every list should start with D regardless, this would suffice as well:
Map[Prepend["D"], DeleteCases[lis1, "D", {3}], {2}]
{{{"D", "J", "W", "L"}, {"D", "Q", "R", "T"}, {"D", "O", "P",
"W"}, {"D", "Z", "L", "M"}}}
And here's one just for fun:
MapThread[RotateLeft, {lis1, {Position[lis1, "D"][[All, -1]] - 1}}, 2]
{{{"D", "W", "L", "J"}, {"D", "Q", "R", "T"}, {"D", "W", "O",
"P"}, {"D", "Z", "L", "M"}}}
lis2 = {{{"J", "D", "W", "A"}, {"Q", "R", "T", "D"},
{"O", "P", "D", "W"}, {"D", "Z", "L", "M"}}};
We can also use SortBy
or Sort
to get the desired results:
If "it doesn't matter what positions the remaining three strings are in":
Map[SortBy[# != "D" &], lis2, {2}]
{{{"D", "A", "J", "W"}, {"D", "Q", "R", "T"}, {"D", "O", "P", "W"}, {"D", "L", "M", "Z"}}}
If the other elements are to be kept in original order,
Map[SortBy[{# != "D" &, False &}], lis2, {2}]
{{{"D", "J", "W", "A"}, {"D", "Q", "R", "T"}, {"D", "O", "P", "W"}, {"D", "Z", "L", "M"}}}
We can use Sort
with a custom ordering function:
ord["D", _] = True;
ord[_, "D"] = False;
ord[a_, b_] := Order[a, b];
Map[Sort[#, ord] &, lis2, {2}]
{{{"D", "A", "J", "W"}, {"D", "Q", "R", "T"}, {"D", "O", "P", "W"}, {"D", "L", "M", "Z"}}}
Use the ord[a_,b_] = 0
to keep the original order of elements other than "D"
:
Map[Sort[#, ord] &, lis2, {2}]
{{{"D", "J", "W", "A"}, {"D", "Q", "R", "T"}, {"D", "O", "P", "W"}, {"D", "Z", "L", "M"}}}
If "it doesn't matter what positions the remaining three strings are in" and no repeated element in each sublist:
prep[x_] := DeleteDuplicates /@ (Prepend[#, "D"] & /@ First@x)
prep@lis1
{{"D", "J", "W", "L"}, {"D", "Q", "R", "T"}, {"D", "O", "P", "W"}, {"D", "Z", "L", "M"}}
Or
lis2 = First@lis1;
prep[x_] := DeleteDuplicates@Prepend[x, "D"]
prep /@ lis2