I have this list:
a={1,1,1,1,2,2,2,2,2,4,4,4,4,6,6,6,6,7,7,7,7}
Now I would like to create a list with the ranges of positions of all same numbers, hence:
range = {{1,4},{5,9},{10,13},{14,17},{18,21}}
How can I do it ?
I have this list:
a={1,1,1,1,2,2,2,2,2,4,4,4,4,6,6,6,6,7,7,7,7}
Now I would like to create a list with the ranges of positions of all same numbers, hence:
range = {{1,4},{5,9},{10,13},{14,17},{18,21}}
How can I do it ?
a = {1, 1, 1, 1, 2, 2, 2, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7, 7};
SplitBy[Transpose[{#, Range@Length@#}], First][[;; , {1, -1}, 2]] &@a
{{1, 4}, {5, 9}, {10, 13}, {14, 17}, {18, 21}}
Here's a solution based on this old gem:
# + {1, 0} & /@ Partition[FoldList[Plus, 0, Length /@ Split[a]], 2, 1]
{{1, 4}, {5, 9}, {10, 13}, {14, 17}, {18, 21}}
list =
{1, 1, 1, 1, 2, 2, 2, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7, 7};
Using SequencePosition (new in 10.1)
SequencePosition[list, {a_, a_ ..}, Overlaps -> False]
{{1, 4}, {5, 9}, {10, 13}, {14, 17}, {18, 21}}
Addendum
As lericr commented it might be better to use Repeated. To show the difference we prepend a 0 to list:
list = {0, 1, 1, 2, 2, 4, 4, 4, 6, 6, 6, 6, 7, 7};
SequencePosition[list, {a_, a_ ..}, Overlaps -> False]
{{2, 3}, {4, 5}, {6, 8}, {9, 12}, {13, 14}}
SequencePosition[list, {Repeated[a_]}, Overlaps -> False]
{{1, 1}, {2, 3}, {4, 5}, {6, 8}, {9, 12}, {13, 14}}
SequencePosition[a, {Repeated[x_]}, Overlaps -> False] might be better, as it works with "singleton" sequences, e.g. {1,1,1,2,3,4,4...}. Of course, we don't know whether that's relevant in OP's situation.
– lericr
Jan 14 '24 at 19:27
list = {1, 1, 1, 1, 2, 2, 2, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7, 7};
Another way is to use Position and MinMax:
Function[x, MinMax@Position[list, x], Listable]@Union@list
({{1, 4}, {5, 9}, {10, 13}, {14, 17}, {18, 21}})
Or using SequenceCases:
SequenceCases[list, {a_ ..} :> MinMax@Position[list, a]]
({{1, 4}, {5, 9}, {10, 13}, {14, 17}, {18, 21}})
The above approach with SequenceCases works very well if the list is not of type {1, 2, 1, 2, 1, 2, 1, 2, 1, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7, 7}, but in the latter case we must add DeleteDuplicates, as pointed out by @eldo.
DeleteDuplicates (to see what I mean, exchange 2s and 1s)
– eldo
Jan 14 '24 at 18:27
DeleteDuplicates and one of the lists with odd positions is for 1 and the other list with even positions is for 2. This is more general, I like it. :-)
– E. Chan-López
Jan 14 '24 at 18:39
Clear["Global`*"];
a = {1, 1, 1, 1, 2, 2, 2, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7, 7};
b1 = {0}~Join~a // Differences // Unitize // Position[#, 1] & //
Flatten
b2 = Length /@ Split[a] // Accumulate
Transpose[{b1, b2}]
{{1, 4}, {5, 9}, {10, 13}, {14, 17}, {18, 21}}
{5,9}, right? – Kuba Oct 26 '17 at 06:48#[[;;, {1,-1}]]&. – Kuba Oct 26 '17 at 06:50Transpose@{Most[# + 1], Rest[#]} &@ DeleteDuplicates@Accumulate@BinCounts[a], – aardvark2012 Oct 26 '17 at 10:45