Table iteration over two ranges

I am trying to create a Table where the iterator has two ranges with different iteration steps.

Let’s consider a simple example: I want to find the square of the numbers from 1 to 9 in steps of 1 and from 50 to 90 in steps of 10. I could do it like this:

Table[i^2, {i, {1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 50, 60, 70, 80, 90}}]

This needs a lot of typing though.

How can I iterate over two ranges without having to type all the numbers by hand?

=================

5

 

Table[i^2, {i, Join[Range[1, 9, 1], Range[50, 90, 10]]}]
– Öskå
Dec 19 ’13 at 13:12

  

 

That’s it! I read about Join and Range but somehow couldn’t figure out how to combine them. Would you mind turning that into an answer?
– frankundfrei
Dec 19 ’13 at 13:26

  

 

@Ymareth answer is good as well, different but good 🙂 Mine is just some basic stuff.
– Öskå
Dec 19 ’13 at 13:29

2

 

Join[Range[1, 9]^2, (10 Range[5, 9])^2]
– Kuba
Dec 19 ’13 at 13:30

1

 

@Öskå Why don’t you make it an answer? It’s good to have simple answers too. Th existing answer is good, but far from ideal for a beginner … there are way too many concepts to understand to make sense of Ymareth’s answer.
– Szabolcs
Dec 19 ’13 at 18:59

=================

3 Answers
3

=================

Well, since I’ve been asked to answer the question in a simple way, here it is:

fun:=#^2&
Table[fun@i, {i, Join[Range[1, 9, 1], Range[50, 90, 10]]}]

{1, 4, 9, 16, 25, 36, 49, 64, 81, 2500, 3600, 4900, 6400, 8100}

Or like @Kuba said:

Join[fun@Range[1,9,1],fun@Range[50,90,10]]

{1, 4, 9, 16, 25, 36, 49, 64, 81, 2500, 3600, 4900, 6400, 8100}

chainTable[expr_, itr : {sym_, __?NumericQ | {__}} ..] := Apply[Join, Map[Function[Null, Table[expr, #], HoldAll], Unevaluated@{itr}]];
SetAttributes[chainTable, HoldAll]; (* As per Jacob’s comment *)

chainTable[x^2, {x, 1, 9}]

{1, 4, 9, 16, 25, 36, 49, 64, 81}

chainTable[x^2, {x, 1, 9}, {x, 10, 90, 10}]

{1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 400, 900, 1600, 2500, 3600, 4900, 6400, 8100}

chainTable[x^2, {x, 1, 9}, {x, 10, 90, 10}, {x, 100, 900, 100}]

{1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 400, 900, 1600, 2500, 3600, \
4900, 6400, 8100, 10000, 40000, 90000, 160000, 250000, 360000, \
490000, 640000, 810000}

chainTable[x^2, {x, 1, 9}, {x, {a, b, c}}]

{1, 4, 9, 16, 25, 36, 49, 64, 81, a^2, b^2, c^2}

Note that sym must be the same in all iterators.

An improved/simplified version which does not repeat the iterator symbol.

chainTable[expr_,{sym_,itr:{PatternSequence[_?NumericQ,_?NumericQ]|PatternSequence[_?NumericQ, _?NumericQ, _?NumericQ]|{__}}..}]:=Apply[Join,Apply[Table[expr,{sym,##}]&,{itr},{1}]];
SetAttributes[chainTable,HoldAll];

chainTable[x^2, {x, {1, 9}, {0, 6, 2}, {{a, b, c}}}]

{1, 4, 9, 16, 25, 36, 49, 64, 81, 0, 4, 16, 36, a^2, b^2, c^2}

Check iterator sym is localized…

x = 1;

chainTable[x^2, {x, {1, 9}, {0, 6, 2}, {{a, b, c}}}]

{1, 4, 9, 16, 25, 36, 49, 64, 81, 0, 4, 16, 36, a^2, b^2, c^2}

  

 

+1, but how about an attribute HoldAll? 🙂
– Jacob Akkerboom
Dec 19 ’13 at 13:26

  

 

hmm I guess then you would have to put Unevaluated around {itr}, and give the function in map attribute HoldAll.
– Jacob Akkerboom
Dec 19 ’13 at 13:30

  

 

HoldAll certainly, not following you with Unevaluated. Can you provide an example that will break?
– Ymareth
Dec 19 ’13 at 13:34

  

 

When you set x = 1 it will break, regardless of a hold attribute
– Jacob Akkerboom
Dec 19 ’13 at 13:36

1

 

If you are only allowing for the iteration of a single variable I see no need to repeat it for each range. I propose this syntax: chainTable[x^2, x, {1, 9}, {10, 90, 10}, {100, 900, 100}]. Or if you get fancy and allow multiple variables: chainTable[x^y, {x, {1, 9}, {10, 90, 10}, {100, 900, 100}}, {y, {…}, …}]. (+1)
– Mr.Wizard♦
Dec 19 ’13 at 14:58

You can use Range to do so:

Table[i^2, {i, Flatten[Append[Range[9], Range[50, 90, 10]]]}]