2

I have the following JavaScript array of many many objects:

[
    {...},
    {...},
    {...},
    .
    .
    .
    .
    .
    {...},
    {...}
]

I would like to transform the array to rows of 3 objects, something like this:

[
    [ {...}, {...}, {...} ],
    [ {...}, {...}, {...} ],
    [ {...}, {...}, {...} ],
    .
    .
    .
    [ {...}, {...}, {...} ],
    [ {...}, {...}, {...} ]
]

What is the best way to do it?

5
  • Do you know the ways to do that and want to know which is the best or do you not know any way to do that? Commented Oct 23, 2012 at 15:16
  • What criteria will you use to decide which array each object should go into? Commented Oct 23, 2012 at 15:16
  • @Renato Lochetti: I always can do it with for statements and loops. I am looking for the efficiect and lesdd code as possible. Maybe there is any hidden function of an array that do such thing that I don't know. Commented Oct 23, 2012 at 15:17
  • @jalynn2: I don't have criteria, each 3 objects should be in one row. I need to transform array to grid. Commented Oct 23, 2012 at 15:18
  • In terms of asymptotic time you always need to iterate for the entire vector. Just a loop and get three at a time. Commented Oct 23, 2012 at 15:19

4 Answers 4

3

Yet another snippet (adapted from @Florent)

var result = [];

do {
   result.push( data.splice( 0, 3 ) )
} while( data.length );
Sign up to request clarification or add additional context in comments.

3 Comments

What if data.length % 3 <> 0 ?
@Naor: well, this code will greedily grab 3 items from the target array and write those into results. If there are less than 3, it'll take whatever is left.
it was flawed anways, fixed that with .push instead of .concat
2

Use a for loop:

var i = 0
  , n = data.length
  , result = [];

for (; i < n; i += 3) {
  result.push([data[i], data[i + 1], data[i + 2]]);
}

5 Comments

preceeding... commas.. argll.. it.. hurts... my.. eyes.. argggh.. +1 anyway :p
fixed it. By the way, the code can get improved by invoking Array.prototype.splice instead using offsets i+n.
The last row might contains undefined where data length is not devided bt 3.
According to the OP's question I supposed that data.length % 3 == 0
The suggested resulting array suggests that :P
2

You can do it with a loop. This takes the array items and creates the array result:

var result = [];
var line;
for (var i = 0; i < items.length; i++) {
  if (i % 3 == 0) {
    line = [];
    result.push(line);
  }
  line.push(items[i]);
}

(This way of looping works even if the source array is not exactly divisible by three.)

2 Comments

You never push the last row if it doesn't divided by 3.
@Naor: Yes, it does. The row is pushed to the array right after it is created, not after it has been filled with items.
0

Just another option :)

var result = arr.reduce(
    function(prev, curr, index) { 
        if(index > 1) { 
            if(prev[prev.length-1].length == 3) 
                prev.push([]); 
            prev[prev.length-1].push(curr); 
            return prev; 
        }
        return [[prev, curr]]; 
    }
);

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.