2

I have an array which is returned from an API in the format of [a, b, c, d, e, f ... ], where a,c,e and b,d,f are of the same type, respectively. Now I want to group the array into [ [a,b], [c,d], [e,f] ...]. It's fairly easy by creating a new array, but the array is large so that could be slow.

So I'm wondering if there're any methods that can do it in-place?

4
  • 2
    means do you want to group them in 2-2 elements Commented Jun 8, 2015 at 3:47
  • 1
    Have you tested creating a new array to see if it is slow? JS is pretty fast now so I wouldn't worry about micro optimisations unless you have found a bottle neck. Commented Jun 8, 2015 at 3:55
  • 1
    It's likely that doing this in-place in the original array will be slower than creating a new array. Changing the type of the array elements on the fly may prevent the array from being optimized. For speed it's best to have all elements in a given array be the same type. Commented Jun 8, 2015 at 4:28
  • @JulianAustralia You're right, this could be immature optimisation. I'm just wondering about what's the fastest method. Commented Jun 8, 2015 at 7:11

3 Answers 3

1

Do you want it in 2 section chunks?

var o    = ['a', 'b', 'c', 'd', 'e', 'f'],
    size = 2, i, ar   = []; // The new array

for (i = 0; i < o.length; i += size) ar.push(o.slice(i,i + size));

Now, ar is:

[
    ['a', 'b'],
    ['c', 'd'],
    ['e', 'f']
]

No matter how you do it, there is alway going to be some looping. The compiler has to go through all the array elements to make the new array.

Speed Tests

So I'll create an array with this:

var l = 10000000, // The length
    o = [], j;
for (j = 0; j < l; j += 1) o.push(j);

So that will make an array with l items now to test the speed:

var start = performance.now(),
    size = 2, ar = [];
for (i = 0; i < o.length; i += size) ar.push(o.slice(i,i + size));
console.log(performance.now() - start);

Tests:

100 Thousand: 0.092909533996135 seconds

1 Million: 0.359059600101318 seconds

10 Million: 10.138852232019417 seconds

The 10 million time might surprise but if you have that big of an array you have bigger problems such as memory issues. And if this array is coming from a server you are probably going to be putting excessive strain on the server.

Sign up to request clarification or add additional context in comments.

Comments

1

This is wanton use of a library even though op is concerned about performance, but I like using lodash/underscore for easily-comprehensible code:

_.partition('a,b,c,d,e,f'.split(','), function(_, idx) {return !(idx % 2);})

1 Comment

Problem is, using a whole new library isn't very efficient in terms of speed
1

An in place solution is to just iterate as normal, building arrays and 'skipping' elements by splicing them before you reach them.

DEMO

var arr = ['a', 'b', 'c', 'd', 'e', 'f'];

function compact (arr) {
  for(var i = 0; i < arr.length; i++) {
    arr[i] = [arr[i], arr[i + 1]];
    arr.splice(i + 1, 1);
  }
  
  return arr; // debug only
}

console.log(compact(arr.slice()));
// >> [["a", "b"], ["c", "d"], ["e", "f"]]

Untested as far as performance goes. I would agree with the comments that it's most likely slower to manipulate the array in place, as apposed to building a new array.

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.