4
$\begingroup$

I have a list of intervals:

Intervals = {{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}}

and a list of measurements:

Measurements = {0.1`, 3.2`, 2.5`, 1.4`, 5.8`, 5.9`}

Now I would like to get the position of the interval which contains the measurement. The following code is working perfectly:

Map[(temp = #; 
   First@Flatten@
     Position[Map[(IntervalMemberQ[Interval[#], temp]) &, Intervals], 
      True]) &, Measurements]

Nevertheless I find the Nestd Map construction not very compelling. Are there any ideas to solve this problem more elgantly?

$\endgroup$
1
$\begingroup$
Flatten[Position[Intervals, x_ /; IntervalMemberQ[Interval[x], #], 
    2] & /@ Measurements]
| improve this answer | |
$\endgroup$
2
$\begingroup$

IntervalMemberQ accepts lists as arguments (either):

IntervalMemberQ[Interval /@ Intervals, #] & /@ Measurements // Position[#, True] & // #[[All, 2]] &
| improve this answer | |
$\endgroup$
  • 1
    $\begingroup$ +1 but may I suggest Flatten[Position[IntervalMemberQ[Interval /@ Intervals, #], True] & /@ Measurements] $\endgroup$ – Chris Degnen Nov 9 '14 at 18:43
2
$\begingroup$
Last /@ Position[
  Thread[IntervalMemberQ[Interval /@ Intervals, #]] & /@ Measurements,
   True]
| improve this answer | |
$\endgroup$
  • $\begingroup$ After multiple tests on the various solutions proposed here (I have personally tested the proposed solutions of Algohi, kguler, ect..). I think your solution is the best. Indeed, it is more robust and solves problems like : Intervals = {{0, 1}, {1, 2}, {0, 2}, {1.5, 2}}; Measurements = {1, 2, 1.5}; For my part, I added : Yourfun[Intervals, {#}] & /@ Measurements For more clarity in the case of multiple inclusions. $\endgroup$ – Doedalos Mar 25 '15 at 8:28
  • $\begingroup$ doedalos@Thanks $\endgroup$ – user18792 Mar 25 '15 at 8:39
1
$\begingroup$

Assuming only that the intervals are sorted.

intervals = {{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}};
measurements = {0.1`, 3.2`, 2.5`, 1.4`, 5.8`, 5.9`};

Map[Function[m,
  Length@TakeWhile[First /@ intervals, m > # &]],
 measurements]

{1, 4, 3, 2, 6, 6}

or

Map[Function[m,
  Count[First /@ intervals, _?(m > # &)]],
 measurements]

{1, 4, 3, 2, 6, 6}

| improve this answer | |
$\endgroup$
1
$\begingroup$

Just for variety (for strictly enclosed):

intervals = {{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}};
measurements = {0.1`, 3.2`, 2.5`, 1.4`, 5.8`, 5.9};

So,

fun[i_, m_] := Pick[i, Sign[# - m] == {-1, 1} & /@ i]
rul = Thread[intervals -> Range[Length@intervals]];

then,

(Join @@ fun[intervals, #] & /@ measurements) /. rul

yields

(*{1, 4, 3, 2, 6, 6}*)
| improve this answer | |
$\endgroup$
1
$\begingroup$
f1 = Function[{k},  Min[Length[#],
                        1 + LengthWhile[ Interval /@ #, ! IntervalMemberQ[#, k] &]]] /@ #2 &;

f1[intervals, measurements]
(* {1, 4, 3, 2, 6, 6} *)

or

Function[{is, ms},  Min[Length[is], 
                        1 + LengthWhile[Times @@@ Subtract[is, #], Positive]] & /@ ms];
f2[intervals, measurements]
(* {1, 4, 3, 2, 6, 6} *)
| improve this answer | |
$\endgroup$
1
$\begingroup$
IntervalMemberQ[Interval /@Intervals, #] & /@ Measurements //Position[#, True] & // #[[All, 2]] &

Here I take the example of @Aisamu and reduce some postfix to make it a little clear.

 (#[[All,2]]&)@(Position[Map[IntervalMemberQ[Interval /@Intervals,#]&,Measurements],True])
| improve this answer | |
$\endgroup$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.