This is a simple article about some of the techniques used in JavaScript arrays. We will use different methods to combine/merge two JS arrays, and discuss the pros/cons of each method.
Let us first consider the following:
Copy Code code as follows:
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var b = ["foo", "Bar", "Baz", "Bam", "Bun", "fun"];
It is clear that the simplest combination of results should be:
Copy Code code as follows:
[
1, 2, 3, 4, 5, 6, 7, 8, 9,
"foo", "Bar", "Baz", "Bam" "Bun", "fun"
]
Concat (..)
This is the most common practice:
Copy Code code as follows:
var C = A.concat (b);
A [1,2,3,4,5,6,7,8,9]
b ["foo", "Bar", "Baz", "Bam", "Bun", "fun"]
C [1,2,3,4,5,6,7,8,9, "foo", "Bar", "Baz", "Bam", "Bun", "fun"]
As you can see, C is an entirely new array that represents a combination of two arrays of A and B, and keeps A and b unchanged. Easy, huh?
But what if a has 10,000 elements, and B has 10,000 elements? C will have 20,000 elements, so a and B's internal memory usage will double.
"No problem!" ", you say. Let them be garbage collected, set A and B to null, the problem solved!
Copy Code code as follows:
A = b = null; ' A ' and ' B ' are recycled.
Oh. For decimal groups with only a few elements, this is no problem. But for large arrays, or for systems with limited memory, this process needs to be repeated frequently, and there are many improvements.
Looping insert
Well, let's copy the contents of one array to another, using: Array#push (..)
Copy Code code as follows:
' B ' onto ' a '
for (Var i=0 i < b.length; i++) {
A.push (B[i]);
}
A [1,2,3,4,5,6,7,8,9, "foo", "Bar", "Baz", "Bam", "Bun", "fun"]
b = null;
Now, array A has the contents of array B.
There seems to be a better memory footprint.
But what if a is a small array? For memory and speed reasons, you might want to put smaller a in front of B. No problem, just push (.. ) replaced by Unshift (..) Can:
Copy Code code as follows:
' A ' into ' B ':
for (var i=a.length-1 i >= 0; i--) {
B.unshift (A[i]);
}
b [1,2,3,4,5,6,7,8,9, "foo", "Bar", "Baz", "Bam", "Bun", "fun"]
Functional skills
But for loops are really ugly and difficult to maintain. Can we do better than that?
This is our first attempt to use the Array#reduce:
Copy Code code as follows:
' B ' onto ' a ':
A = B.reduce (function (Coll,item) {
Coll.push (item);
return Coll;
}, a);
A [1,2,3,4,5,6,7,8,9, "foo", "Bar", "Baz", "Bam", "Bun", "fun"]
Or ' A ' into ' B ':
b = a.reduceright (function (Coll,item) {
Coll.unshift (item);
return Coll;
}, B);
b [1,2,3,4,5,6,7,8,9, "foo", "Bar", "Baz", "Bam", "Bun", "fun"]
Array#reduce (..) and Array#reduceright (..) Was nice, but they were a little clumsy. Es6=> 's arrow function will reduce the amount of code, but it still needs a function, each element needs to be called once, not perfect.
So how about this one:
Copy Code code as follows:
' B ' onto ' a ':
A.push.apply (A, b);
A [1,2,3,4,5,6,7,8,9, "foo", "Bar", "Baz", "Bam", "Bun", "fun"]
Or ' A ' into ' B ':
B.unshift.apply (b, a);
b [1,2,3,4,5,6,7,8,9, "foo", "Bar", "Baz", "Bam", "Bun", "fun"]
This is a lot better, right? Especially since Unshift (..) Method here does not need to worry about the reverse sort in front. ES6 's spead operations will be more beautiful: A.push (... b) or b.unshift (... a)
Array Maximum length limit
The first major problem is that memory usage has increased by one-fold (of course, only temporarily!). The appended content is essentially copying the elements into the stack through a function call. In addition, the different JS engine has the limit of the length of copy data.
So, if the array has 1 million elements, you're definitely going to go beyond the push (...). Or Unshift (...) Limits that allow call stacks. Alas, it will do well to handle thousands of elements, but you must be careful not to exceed a reasonable length limit.
Note: You can try Splice (...) with a push (...) and Unshift (...) There are problems like this.
There is a way to avoid this maximum length limit.
Copy Code code as follows:
function Combineinto (a,b) {
var len = a.length;
for (Var i=0 i < Len; i=i+5000) {
B.unshift.apply (b, A.slice (I, i+5000));
}
}
Wait a minute, our readability is backwards. That's it, it's probably going to get worse, uh.