admin管理员组

文章数量:1355077

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
Add a ment  | 

4 Answers 4

Reset to default 4

Since 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

本文标签: javascriptMove every other value from array into a new arrayStack Overflow