5
$\begingroup$

I am trying to do the following:

I have a list, say:

a = {{1}, {2}, {3}, {4},{5},{6}}

and a list which specifies the range:

range = {{1, 3}, {4, 6}};

Now I would like to receive a list, which gathers elementwise all list elements of list a within the range of "range".

The result should be:

result = {{1,2,3},{4,5,6}}

What I tried:

t = {};
result = AppendTo[t, a[[#[[1]], #[[2]] ]] ] & /@ a

But it does not work.

$\endgroup$
1
  • $\begingroup$ Although not answering your specific question, TakeDrop might be worth considering? TakeDrop[Flatten@a, 3] or TakeDrop[Flatten@a, First@range] $\endgroup$
    – user1066
    Oct 25, 2017 at 22:19

6 Answers 6

8
$\begingroup$

I think this is what you want:

Flatten[Take[a, #]] & /@ range

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

$\endgroup$
7
$\begingroup$
result = Range @@@ range

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

Or more like your own code:

a = {{1}, {2}, {3}, {4}, {5}, {6}};
range = {{1, 3}, {4, 6}};
t = {};
result = Last[AppendTo[t, a[[#[[1]] ;; #[[2]], 1]]] & /@ range]
$\endgroup$
5
  • $\begingroup$ Thanks a lot ! Why are you not using a in the first solution ? $\endgroup$
    – james
    Oct 25, 2017 at 16:29
  • $\begingroup$ How would you do it, if a would be: a = {1, 2, 3, 4, 5, 6} ? $\endgroup$
    – james
    Oct 25, 2017 at 16:36
  • $\begingroup$ @totyped For a = {{1}, {2}, {3}, {4}, {5}, {6}} you want the output {{1,2,3}, {4,5,6}} and for a = {1, 2, 3, 4, 5, 6} i don't understand how the output should change. What should output be? $\endgroup$
    – Coolwater
    Oct 25, 2017 at 16:44
  • $\begingroup$ The output should be the same. $\endgroup$
    – james
    Oct 25, 2017 at 16:49
  • $\begingroup$ @totyped That's why i don't use a in the first one. I the second you would need to remove , 1 $\endgroup$
    – Coolwater
    Oct 25, 2017 at 16:50
5
$\begingroup$
a = {{1}, {2}, {3}, {4}, {5}, {6}} // Flatten;

range = {{1, 3}, {4, 6}};

Pick[a, #] & /@ Outer[IntervalMemberQ[Interval[#1], #2] &,
  range, a, 1]

(* {{1, 2, 3}, {4, 5, 6}} *)
$\endgroup$
5
$\begingroup$

I may be missing the point here, but it seems to me that there is some ambiguity in what constitutes a generalization of the question, and the answers posted appear to be generalizing in quite different ways and/or answering quite different questions.

This ambiguity stems from the nice sequential ordering of a and range, but one interpretation (possibly just mine) of the requirement

"I would like to receive a list, which gathers elementwise all list elements of list a within the range of range"

can be better illustrated by the following less nice example:

SeedRandom[1]
a = Sort@RandomSample[List /@ Range[20], 10]
range = {{1, #}, {# + 1, 20}} &@ RandomInteger[{Min[a] + 1, Max[a] - 2}]

(* {{1}, {2}, {6}, {8}, {9}, {11}, {13}, {16}, {17}, {19}} *)

(* {{1, 5}, {6, 20}} *)

The "correct" output (again, according to me, and possibly not to the OP) should be

(* {{1, 2}, {6, 8, 9, 11, 13, 16, 17, 19}} *)

which (as far as I can tell) only @Nasser's Map and @BobHanlon's Pick provide. (Obviously, this is still "nice" to some extent -- I'm assuming a is an ordered list of integers, range is composed of only two intervals, etc..)

Here's an assortment of other functions which provide the "correct" answer:

Pick[Flatten[a], UnitStep[Flatten[a] - range[[2, 1]]], #] & /@ {0, 1}

TakeDrop[#, First@FirstPosition[#, x_ /; x > range[[1, 2]]] - 1] &@ Flatten[a]

GatherBy[Flatten[a], # <= range[[1, 2]] &]

Last@Reap[Scan[Sow[#, # <= range[[1, 2]]] &, Flatten[a]]]

(They also give the right output for the example in the question.)

$\endgroup$
1
  • 1
    $\begingroup$ Indeed, I open a question and see instead of vtc because unclear, lots of answers, yet I am completely baffled as to op's actual intent. Why must a be a nested list, for example? $\endgroup$
    – LLlAMnYP
    Oct 26, 2017 at 5:46
4
$\begingroup$
Flatten[a[[Span @@ #]]] & /@ range

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

or

Extract[a, List /@ (Range @@@ range), Flatten]

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

Further examples:

Extract[Range[0, 100, 10], List /@ (Range @@@ range), Flatten]

{{0, 10, 20}, {30, 40, 50}}

Extract[CharacterRange["A","Z"], List /@ (Range @@@ range), Flatten]

{{"A", "B", "C"}, {"D", "E", "F"}}

$\endgroup$
4
$\begingroup$

Using Intersection

a = Flatten@{{1}, {2}, {3}, {4}, {5}, {6}};
range = Range @@@ {{1, 3}, {4, 6}};

And now

Map[Intersection[a, #] &, range]

Mathematica graphics

Lets say your data now becomes

a = Flatten@{{1}, {2}, {5}, {6}};

Then

Map[Intersection[a, #] &, range]

Mathematica graphics

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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