Message Boards Message Boards

1
|
5090 Views
|
3 Replies
|
9 Total Likes
View groups...
Share
Share this post:

Number items in a list of lists, Functional programming alternative?

Posted 7 years ago

The code below assigns a sequential number to each item in a list of lists. The code is written in a procedural programming style.
Seeking recommendations for re-writing this in functional programming style that would be:

  • more compact
  • readable to intermediate level Mathematica users

All recommendations are welcome.

    vec1 = {a, b, c, d};(* data vector*)
    vec2 = {a, b, c, d, e, f};(* data vector*)
    vec3 = {a, b, c};(* data vector*)
    allVecs = {vec1, vec2, vec3} (*sample data. Both the number of vectors and the length of each vector are arbitrary*)
    nEach = Length@# & /@ allVecs;(*length of each data vector*)
    allIndices =  Range@Total@ nEach;(*list of indices, one index for each entry in the sample data*)
    lPos = FoldList[Plus, 0,  nEach];(*start and stop positions of each data vector. start positions are 0 offset*)

    iA = {}; (*this list is the goal:  sequential numbering of each data  item*)
    iInd = {};(*list of indices corresponding to each data vector*)
    For[ i = 1, i <=  Length@nEach, i++,
        AppendTo[iInd, allIndices[[lPos[[i]] + 1 ;; lPos[[i + 1]]]] ];
        AppendTo[iA, Transpose[{iInd[[i]], allVecs[[i]]}] ];
    ]
    iInd;
    iA (*result*)
    (* data:  {{a, b, c, d}, {a, b, c, d, e, f}, {a, b, c}} *) 
    (* result: {{{1, a}, {2, b}, {3, c}, {4, d}}, {{5, a}, {6, b}, {7, c}, {8, 
    d}, {9, e}, {10, f}}, {{11, a}, {12, b}, {13, c}}} *)
Attachments:
POSTED BY: Robert McHugh
3 Replies
Posted 7 years ago

Thanks for answering. 9 lines of code down to 2.
So much to learn about using this tool properly!

POSTED BY: Robert McHugh
vec1 = {a, b, c, d};
vec2 = {a, b, c, d, e, f}; 
vec3 = {a, b, c};  
f[v1_, v2_, v3_] := 
 Block[{i = 1}, Map[Map[{i++, #} &, #] &, {v1, v2, v3}]]
f[vec1, vec2, vec3]

out: {{{1, a}, {2, b}, {3, c}, {4, d}}, {{5, a}, {6, b}, {7, c}, {8, d}, {9, e}, {10, f}}, {{11, a}, {12, b}, {13, c}}}

POSTED BY: l van Veen

You could use:

i = 0;
Map[{++i, #} &, allVecs, {2}]

or

i = 0;
Replace[allVecs, x_ :> {++i, x}, {2}]

or

Internal`PartitionRagged[MapIndexed[{#2[[1]], #1} &, Join @@ allVecs], Length /@ allVecs]

or

tmp = Join @@ allVecs
tmp = Transpose[{Range[Length[tmp]], tmp}];
Internal`PartitionRagged[tmp, Length /@ allVecs]

or

tmp = Join @@ allVecs
tmp = Transpose[{Range[Length[tmp]], tmp}];
lens = Length /@ allVecs;
begins = Accumulate[Prepend[Most[lens], 1]];
ends = Accumulate[lens];
MapThread[tmp[[#1 ;; #2]] &, {begins, ends}]

or

pos = Position[allVecs, _, {2}, Heads -> False]
numbers = Range[Length[pos]]
replacements = MapThread[#1 -> {#2, Extract[allVecs, #1]} &, {pos, numbers}]
ReplacePart[allVecs, replacements]
POSTED BY: Sander Huisman
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract