简体   繁体   中英

how can I concatenate two arrays in javascript?

I saw this response for extending one array with another so I tried:

console.log(['a', 'b'].push.apply(['c', 'd']));

but it prints:

2

shouldn't it print:

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

if not what was i doing wrong?

if not what was i doing wrong?

First of all, .push returns the new length of the array:

var arr = [1, 1, 1];
console.log(arr.push(1)); // 4
console.log(arr); // [1, 1, 1, 1]

Second, .apply needs two arguments: The object you want to apply the function to, and an array of arguments. You only pass a single argument, so your code is basically equivalent to:

['c', 'd'].push()

Ie you are not adding anything to the ['c', 'd'] array. That also explains why you see 2 in the output: ['c', 'd'] has length 2 and .push() doesn't add any elements to it so it still has length 2 .

If you want to use .push to mutate the original array (instead of creating a new one like .concat does), it would have to look like:

var arr = ['a', 'b'];
arr.push.apply(arr, ['c', 'd']); // equivalent to Array.prototype.push.apply(arr, [...])
//              ^   ^--------^
//    apply to arr   arguments
console.log(arr); // ['a', 'b', 'c', 'd']

See also

尝试这个:

 console.log(['a', 'b'].concat(['c', 'd']));

If your scenario allows for ES6 syntax, you can use the spread element to concatenate arrays:

var arr1 = [1,2];
var arr2 = [3,4];
var arr3 = [...arr1, ...arr2];
console.log(arr3); // Logs [1,2,3,4]

If you're using a modern browser then you can use the spread operator, ... like so:

console.log([...['a', 'b'], ...['c', 'd']])

If you're using an older browser/no transpiler then concat is the way to go:

console.log(['a', 'b'].concat(['c', 'd']))

As there seems to be a general misunderstanding here about the use of various array appending methods I will add to it with the safest alternative to ES6's introduction of the spread operator

Functional language

Functional languages were developed to simplify code development allowing programmers and systems engineers to define functions to replace common operations/algorithms. JS is a functional language, you write functions to make life easier, save you typing and making the program easier to test and validate, so why fight it with dangerous alternatives .

The mistake being made in the answers (with the exception of Jonathan Michalik answer) is they are all trying to either coerce the language into doing something that should be done by a function ( Function.apply ), or providing a solution without explanation of what it is doing ( Array.concat ).

Write a function to append arrays, for example.

function appendArray(array,array1){ // adds the items in array1 
                                    // array1 can be any type
                                    // to the end of array 
    var len,i;
    array1 = [].concat(array1);   // ensure array1 is an array
    len = array1.length;
    i = 0;
    while(i < len){
        array[array.length] = array1[i++]; // this is 2* quicker than invoking push
    }
    return array;
}

For the 60 seconds it takes to write, or less to include as part of a general library you have created a safe and general purpose array append function.

log(appendArray([0, 1, 2, 3], 4)); // 0,1,2,3,4
log(appendArray([0, 1, 2, 3], [4, 5, 6])); // 0,1,2,3,4,5,6

Now to why the other answers are not good solutions.

Array.concat

is the safer option, and should be used if you are in control of all references to the array. It suffers from the fact that it creates a new array when it is used.

var array1 = [1,2,3];
var array2 = [4,5,6];
array1 = array1.concat(array2); // 1,2,3,4,5,6

Many are under the mistaken belief that the concat( array2 ) is added to array1, it is not, it is added to a copy of array1. If you have other references to the original array then you end up creating a copy of the concatenated array, while the original array remains in memory.

function doSomething(array){
    ... generate some info
    array.concat(info);
}

var myArray = [...someData];  // the array
var myObject.setArray(myArray); // create a new referance to the array in myObject
myArray = doSomething(myArray);  // adds info via concat to the array.

It is not immediately apparent, but you now have two arrays the original inside myObject, and the concatenated version in myObject which may store the array referance in closure, that you can not change or delete unless you dereference all associated context. Nor do you know how many references to the original array exist.

Function.apply()

There are many reasons not to use this function but of particular note is using it on the Array.push function. It suffers from indeterminacy if you use it without type checking the arrays.

var myArray = [1,2,3,4];
var data = getSomeData(); // may return array or array like data
myArray = doSomeWorkOn(myArray); // the spec says this may return undefined
myArray.push.apply(myArray,data); // what happen here is indeterminate and
                                     // depends on the JS context, the JS mode
                                     // and the JS version

Without vetting myArray for undefined you can not predict what the result of apply will be. It could throw and error, or it may silently fail if the global scope has a push function and you are not in strict mode.

Without knowing the JS version ES5 or ES6 the apply may have pushed one object data onto myArray, or all the items in data ES5 does not recognise array like objects as arrays for Function.apply while ES6 does. So you must vet myArray , or data to be of the correct type for the current JS version.

Arguments have limits that are dependent on the current JS context, there is also inconsistency between JS context's handling of long argument lists. Some will throw an error, others will simply truncate the arguments.

var myPixelData = [];
myPixelData.push.apply(myPixelData,getSomePixelData()); // what will happen????

This may throw, or it may work, or it may have only pushed 65535 items onto the array, or more, or less. You will have to wrap it in a try catch, and vet the results against the length of the array returned by getPixelData . All the added complexity just to make it easier???

So why use Function.apply on Array.push or use Array.concat when it is so much easier to write a function to do what you want and save you from a long list of problems, ambiguities, and errors.

You should try this:

a= ['a', 'b'];
b= ['c', 'd'];
a.push.apply(a,b);

console.log(a);

you should use variables like so

  <script type="text/javascript"> var arr1=['a', 'b']; var arr2=['c', 'd']; Array.prototype.push.apply(arr1, arr2); console.log(arr1); </script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM