# How to identify intervals for each integer number

I have two lists:

lst1 = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
lst2 = Range[0.1, 10, 0.1];


How can find the interval from lst2 for each integer number in lst1?

For example, lst1 starts with integer 4 corresponding to 0.1 (first element in lst2), and it repeats 30 times. Then the 30th element in lst2 (which is 3) should match with the last 4 in lst1. So, the interval of interest for this example is {4, [0.1, 3]}, meaning that 4 remains constant in the range [0.1, 3]. I have a very long list about 10000 of monotonically increasing positive numbers in lst2 and a limited number of integers, positive but not necessarily monotonically increasing.

Map[{#[[1, 1]], MinMax @ #[[All, 2]]} &] @
SplitBy[Transpose[{##}], First] &[lst1, lst2]

{{4,{0.1, 3.}}, {5, {3.1, 4.8}}, {4, {4.9, 7.5}}, {3, {7.6, 8.5}},
{2, {8.6, 10.}}}

• Is there any problem with Transpose? I receive an error relating to Transpose. Commented Feb 11 at 16:00
• can you share the error/warning message?
– kglr
Commented Feb 11 at 16:10
• Transpose::nmtx: The first two levels of {{4,4,4,4,4,4,4,4,4,4,<<4990>>},{0.0001,0.0002,0.0003,0.0004,0.0005,0.0006,0.0007,0.0008,0.0009,0.001,<<9990>>}} cannot be transposed. is the error. Commented Feb 11 at 16:14
• lst1 and lst2 should have the same length. If not, you can try Map[{#[[1, 1]], MinMax @ #[[All, 2]]} &] @ SplitBy[Transpose[{##}], First] &[lst1,Take[ lst2, Length@lst1].
– kglr
Commented Feb 11 at 16:16
• It works now! Thanks. Commented Feb 11 at 16:23
Transpose[{First /@ #, MinMax /@
TakeList[lst2, Length /@ #]}] & [Split @ lst1]


{{4, {0.1, 3.}}, {5, {3.1, 4.8}}, {4, {4.9, 7.5}}, {3, {7.6, 8.5}}, {2, {8.6, 10.}}}

Clear["Global*"];

lst1 = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
lst2 = Range[0.1, 10, 0.1]

(Transpose[{lst1, lst2}] // SplitBy[#, First] & //
Map[Through[{First, Last}[#]] &]) /. { {a_, b_}, {c_,
d_}} :> {a, {b, d}}


I wouldn't run it on a very long list, but for variety:

Using SequenceReplace:

SequenceReplace[Transpose[{lst1, lst2}],
k : {{a_, b_}, Shortest[{a_, _} ..], {a_, d_}} :> {a, {Last@First@k,
Last@Last@k}}]


Result:

{{4, {0.1, 3.}}, {5, {3.1, 4.8}}, {4, {4.9, 7.5}}, {3, {7.6, 8.5}}, {2, {8.6, 10.}}}

lst1 = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};

lst2 = Range[0.1, 10, 0.1];


{#1[[1]], #2[[{1, -1}]]} & @@@ Map[Thread]@SplitBy[Thread[{lst1, lst2}], First]


Result:

{{4, {0.1, 3.}}, {5, {3.1, 4.8}}, {4, {4.9, 7.5}}, {3, {7.6, 8.5}}, {2, {8.6, 10.}}}

Or using SequenceCases:

patt = k : {Shortest[{a_, _} ..]} :> {a, {k[[1, -1]], k[[-1, 2]]}};



Result:

{{4, {0.1, 3.}}, {5, {3.1, 4.8}}, {4, {4.9, 7.5}}, {3, {7.6, 8.5}}, {2, {8.6, 10.}}}

FoldPairList[
TakeDrop,
lst2,
Map[Length] @ Split[lst1],
{lst1[[-1 - Length @ Last @ #]], #[[1, {1, -1}]]} &]

{{4, {0.1, 3.}}, {5, {3.1, 4.8}}, {4, {4.9, 7.5}},
{3, {7.6, 8.5}}, {2, {8.6, 10.}}}

MapThread[
{First @ #1, MinMax @ #2} &,
{#, InternalCopyListStructure[#, lst2]}] & [Split @ lst1]


{{4, {0.1, 3.}}, {5, {3.1, 4.8}}, {4, {4.9, 7.5}}, {3, {7.6, 8.5}}, {2, {8.6, 10.}}}