Many experienced users on this site tend to use Map (and its variants, MapAt, MapIndexed, etc.) rather than Table. When applying the same operation to every element of an array, Map does seem more semantically direct. For instance:
test2D = {{a1, a2, a3}, {b1, b2}, {c1, c2, c3, c4}};
Table[g[test2D[[row, col]]] + 1, {row, 1, Length@test2D}, {col, 1, Length@test2D[[row]]}];
MatrixForm[%, TableAlignments -> Left]
Map[g[#] + 1 &, test2D, {2}];
MatrixForm[%, TableAlignments -> Left]
But when I need to carry out index-specific (i.e., position-specific) operations on higher-dimensional(>=2D) arrays, I find Map and its variants more challenging than Table.
For instance, suppose I want to raise each element in a 1D array to a power equal to its position. That I can do with either Table or MapIndexed:
test1D = {a1, a2, a3};
Table[test1D[[col]]^col, {col, 1, Length@test1D}]
Flatten[MapIndexed[#1^#2 &, test1D], 1]
But suppose I want to raise each element in a 2D array to a power equal to its row no. x column no. With Table that's conceptually straightforward:
Table[test2D[[row, col]]^(row*col), {row, 1, Length@test2D}, {col, 1, Length@test2D[[row]]}]
But how would one do that with MapIndexed? It would be nice if it were just something like:
MapIndexed[#1^(#2*#3) &, test2D]
where #2 were the column index and #3 were the row index, but it doesn't work like that.
Finally, suppose you have more detailed index-specific operations in a 2D array. That seems to be where Table really shines, but I'd be interested to hear of alternatives. E.g., suppose that, from each successive 4-element block of data in a row, you need to extract the 2nd and 4th elements, but only when all four elements are present. Thus, in a row of {a1, a2, a3, a4, a5, a6, a7, a8, a9, a10}, you need {{a2, a4}, {a6, a8}}. And you need to do this for each successive row. Further, the rows have variable lengths. With Table, this does the job:
test2Dx = {{a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13,
a14, a15, a16, a17, a18, a19, a20}, {b1, b2, b3, b4, b5, b6, b7,
b8, b9, b10, b11}, {c1, c2, c3, c4, c5, c6, c7}, {d1, d2, d3, d4,
d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17}};
Table[{test2Dx[[row, 2 + col*4]], test2Dx[[row, 4 + col*4]]}, {row, 1, Length@test2Dx}, {col, 0, (Floor[N[Length[test2Dx[[row]]]/4]]) - 1}];
MatrixForm[%, TableAlignments -> Left]
Is there a semantically straightforward way to do this using other functions (e.g., Map or its variants and a pure function)—or is this a use case for which Table makes more sense?