I have two one-dimensional arrays, a
and b
. a
has values and b
is empty. The length of a
is an even number. I'd like to remove every other value from a
and move them to b
, in the same order as they were placed in a
.
var a = [1, 2, 3, 4, 5, 6], b = [];
bees
var a = [1, 3, 5], b = [2, 4, 6];
I figured that filter
would do the trick but I'm not that happy with the performance of it since the average length of a
is 300-400.
b = a.filter((i, idx) => {
return idx % 2 == 0;
});
a = a.filter((i, idx) => {
return idx % 2 == 1;
});
I've also been looking at lodash to see if that library had anything that might help me and the only function that's near what I'm looking for is _.chunk(array, \[size=1\])
.
I appreciate any and all help to help me figure out a better, faster way to do this.
I have two one-dimensional arrays, a
and b
. a
has values and b
is empty. The length of a
is an even number. I'd like to remove every other value from a
and move them to b
, in the same order as they were placed in a
.
var a = [1, 2, 3, 4, 5, 6], b = [];
bees
var a = [1, 3, 5], b = [2, 4, 6];
I figured that filter
would do the trick but I'm not that happy with the performance of it since the average length of a
is 300-400.
b = a.filter((i, idx) => {
return idx % 2 == 0;
});
a = a.filter((i, idx) => {
return idx % 2 == 1;
});
I've also been looking at lodash to see if that library had anything that might help me and the only function that's near what I'm looking for is _.chunk(array, \[size=1\])
.
I appreciate any and all help to help me figure out a better, faster way to do this.
Share Improve this question edited Jun 20, 2017 at 14:59 chazsolo 8,5441 gold badge24 silver badges45 bronze badges asked Jun 20, 2017 at 14:05 MagnusMagnus 4271 gold badge8 silver badges35 bronze badges 5- Filtering a small array of 400 elements should be nearly instantaneous. What do you mean you're not happy with the performance? Are you noticing delays? It could be done in a single iteration, but it won't make much difference – salezica Commented Jun 20, 2017 at 14:43
- You could benchmark the given answers for performance, would be really interesting to see how lodash performs against vanilla js e.g.. – Hinrich Commented Jun 20, 2017 at 15:28
- @slezica I agree it would not make a noticable difference with 400 elements. Still, if this gets executed a lot of times, it could. – Hinrich Commented Jun 20, 2017 at 15:36
- @Hinrich Great idea, I'll set up a jsperf test with all of your answers. – Magnus Commented Jun 20, 2017 at 17:54
- 1 Here's a performance test for all of your answers, thank you so much for your help! jsperf./move-every-other-value-from-array-into-a-new-array – Magnus Commented Jun 20, 2017 at 18:14
4 Answers
Reset to default 4Since you mentioned lodash you could do this with _.partition:
let a = [1, 2, 3, 4, 5, 6];
let b = [];
let i = -1;
[a, b] = _.partition(a, (item) => i++ % 2);
console.log(a);
console.log(b);
<script src="https://cdn.jsdelivr/lodash/4.17.4/lodash.min.js"></script>
Partition's predicate is the identity function, which doesn't include the index of the item, so this es with a promise of an external index i
.
Of course, you could always wrap this functionality into it's own function:
const splitEvenOdd = (array, i = -1) => _.partition(array, (item) => i++ % 2);
let a = [1, 2, 3, 4, 5, 6];
let b = [];
[a, b] = splitEvenOdd(a);
console.log(a);
console.log(b);
<script src="https://cdn.jsdelivr/lodash/4.17.4/lodash.min.js"></script>
Vanilla JS ES5, simple and clean.
var a = [1, 2, 3, 4, 5, 6], b = [];
for(var i = a.length-1; i >= 0; i--) {
if(i % 2 === 1) {
b.unshift(a.splice(i, 1)[0])
}
}
Basically, it is iterating through a
backwards, and if the condition is true splicing the item und adding it as first item of b
.
To loop through the source once, the values can be added to a specific array depending on the index. For example:
const source = [1, 2, 3, 4, 5, 6];
let arrs = [[],[]];
for(let i = 0; i< source.length; i++)
arrs[i%2].push(source[i]);
let [a,b] = arrs;
console.log(a);
console.log(b);
Alternatively, if it's important to alter the original arrays, a
can be filled in a direct iteration, since the index being processed is always ahead of the one being filled:
let a = [1, 2, 3, 4, 5, 6], b= [];
for(let i = 0; i< a.length; i++)
(i % 2 ? b : a)[Math.floor(i/2)] = a[i];
a.splice(a.length/2);
console.log(a);
console.log(b);
The best performance you can get for this is 0(n) or linear time since you have to iterate through the entire array. What may help is reducing the number of loops
var a=[];
var b=[];
function splitArray(arr)
{
for (var i=0;i<arr.length;++i)
{
if (arr[i]%2 == 0)
b.push(arr[i]);
else
a.push(arr[i]);
}
}
What this does is reduces the number of times you have to iterate through the original array from 2 to 1