Compares the methods and advantages of JS array merging, and the advantages and disadvantages of js array Merging
Original article: Combining JS Arrays
Original Article Date:
Translation Date:
Translated by: Tie
This article is a basic JavaScript skill. We will learn a variety of common methods to combine/merge two JS arrays, and compare the advantages and disadvantages of various methods.
Let's take a look at the specific scenarios:
var q = [ 5, 5, 1, 9, 9, 6, 4, 5, 8];var b = [ "tie", "mao", "csdn", "ren", "fu", "fei" ];
Obviously, the result of simple concatenation of array q and array B is:
[ 5, 5, 1, 9, 9, 6, 4, 5, 8, "tie", "mao", "csdn", "ren", "fu", "fei"]
Concat (...) Method
The most common usage is as follows:
var c = q.concat( b );q; // [5,5,1,9,9,6,4,5,8]b; // ["tie","mao","csdn","ren","fu","fei"];c; // [5,5,1,9,9,6,4,5,8,"tie","mao","csdn","ren","fu","fei"]
As you can see,
CIs a brand new array, indicating
QAnd
BThe combination of the two arrays,
QAnd
BIt's useless now, right?
If
QArray has
10000Elements,
BArrays also have
10000Elements? Then Array
CNow there are 20000 elements. This method consumes 2 times of memory.
"No problem !", You may think that, if q and B are left blank, they will be reclaimed, right? Problem solved!
Q = B = null; // 'Q' and 'B' can be recycled now
Amount? If the array is small, there is no problem, but the memory is limited when large arrays or repeated processing is required, and it needs to be optimized.
Loop insert
OK. Let's add the content of an array to another one.
Array # push ()Method:
// Insert 'B' into array 'q' for (var I = 0; I <B. length; I ++) {q. push (B [I]);} q; // [5, 5, 9, 6, 8, "tie", "mao", "csdn", "ren ", "fu", "fei"] B = null;
Now, q stores the content of two original arrays (q + B ).
It seems that the memory optimization is good.
However, if
QThe array is small and
BHow big is it? For memory and Speed considerations
QInsert
BAbove. No problem, just use
Unshift ()Method substitution
Push ()You can, the corresponding loop traversal also needs to be performed from large to small:
// `q` into `b`:for (var i=q.length-1; i >= 0; i--) { b.unshift( q[i] );}b; // [5,5,1,9,9,6,4,5,8,"tie","mao","csdn","ren","fu","fei"]q = null;
Practical Skills
Sadly, the for loop is very earthy and difficult to maintain. Can we do better?
Let's try it first.
Array # reduce:
// `b` onto `q`:q = b.reduce( function(coll,item){ coll.push( item ); return coll;}, q );q; // [5,5,1,9,9,6,4,5,8,"tie","mao","csdn","ren","fu","fei"]// or `q` into `b`:b = q.reduceRight( function(coll,item){ coll.unshift( item ); return coll;}, b );b; // [5,5,1,9,9,6,4,5,8,"tie","mao","csdn","ren","fu","fei"]
Array # reduce ()And
Array # reduceRight ()Very large, but a little bulky, and the average person cannot remember. JS specification 6
=>Arrow-functions can greatly reduce the amount of Code. However, it is also a waste to execute function calls on each array element.
What about the following code?
// `b` onto `q`:q.push.apply( q, b );q; // [5,5,1,9,9,6,4,5,8,"tie","mao","csdn","ren","fu","fei"]// or `q` into `b`:b.unshift.apply( b, q );b; // [5,5,1,9,9,6,4,5,8,"tie","mao","csdn","ren","fu","fei"]
BIG is higher, right !? Especially
Unshift ()The method does not need to consider the reverse sequence. ES6 expansion operator (spread operator, add
...Prefix) is even higher:
A. push (... B)Or
B. unshift (...)
However, in fact, this method is too optimistic. In both cases, whether it is to pass a or B
Apply ()As the second parameter (when the Function is called using the apply method, the first parameter becomes this internally, that is, context, and scope ).
...In fact, all arrays are split into functions by expanding operators.
Arguments.
The first major problem is that the memory usage doubles (of course, it's temporary !), Because the array needs to be copied to the function stack. In addition, different JS engines have different implementation algorithms, which may limit the number of parameters that can be passed by the function.
If 1 million elements are added to the array, the size of the array must exceed the size allowed by the function stack.
Push ()Or
Unshift ()Call. This method is only available for thousands of elements, so it must be limited to a certain range.
Note:: You can also try
Splice ()He and
Push (..)/unshift (..)They all have the same restrictions.
One option is to continue using this method, but batch processing is adopted:
Function combineInto (q, B) {var len = q. length; for (var I = 0; I <len; I = I + 5000) {// process 5000 pieces of B at a time. unshift. apply (B, q. slice (I, I + 5000 ));}}
And so on. We damage the readability of the Code (or even the performance !). Let's end this journey before we give up.
Summary
Array # concat ()It is a tested method used to combine two or more arrays, but it creates a new array instead of modifying an existing one.
There are many workarounds, but they all have different advantages and disadvantages and need to be selected based on the actual situation.
The advantages/disadvantages listed above, and perhaps the best (including those not listed) method is
Reduce (..)And
ReduceRight (..)
Whatever you choose, you should think about your array merging strategy critically, instead of taking it for granted.
JS array Merging
This is an object, not an array.
It took me some time to write a function. Please add more points
<! -- Status OK -->
<! Doctype html public "-// W3C // dtd html 4.01 Transitional // EN">
<Html>
<Head>
<Meta http-equiv = "Content-Type" content = "text/html; charset = gb2312"/>
<Title> JS array merging question _ Baidu Knows </title>
<Link rel = "alternate" type = "application/rss + xml" title = "latest answer to" JS array merging question "(RSS 2.0)" href = "zhidao.baidu.com/..w.rssqb">
</Head>
<Body>
<Script>
Function objConcat (a1, a2 ){
Var newarr = {};
For (var k1 in a1 ){
Newarr [k1] = a1 [k1];
}
For (var k2 in a2 ){
Newarr [k2] = a2 [k2];
}
Return newarr;
}
Arr1 = {a: 1, B: 2, c: 3 };
Arr2 = {B: 5, h: 6, k: 7 };
Arr = objConcat (arr1, arr2 );
For (var key in arr ){
Document. write (key + '->' + arr [key] + '</br> ');
}
</Script>
</Body>
</Html>
In js, how does one combine the array content with two new Object arrays and repeat the content?
If it is a common data type, it is very simple
Var ARR1 = [1, 2, 4];
Var ARR2 = [3, 4, 5, 6];
Function mergeArray (arr1, arr2 ){
Var _ arr = [];
For (var I = 0; I <arr1.length; I ++ ){
_ Arr. push (arr1 [I]);
}
Var _ dup;
For (var I = 0; I <arr2.length; I ++ ){
_ Dup = false;
For (var _ I = 0; _ I <arr1.length; _ I ++ ){
If (arr2 [I] === arr1 [_ I]) {
_ Dup = true;
Break;
}
}
If (! _ Dup ){
_ Arr. push (arr2 [I]);
}
}
Return _ arr;
}
Var B = mergeArray (ARR1, ARR2 );
// B = [1, 2, 3, 4, 5, 6]
// The upstairs method returns ['1', '2', '3', '4', '5'] and converts it to a string.
If it is a complex object and an array, it is a little more troublesome and needs to be compared after serialization
Object. prototype. Serialize = function ()
{
Var type = _ typeof _ (this );
Switch (type)
{
Case 'array ':
{
Var strArray = '[';
For (var I = 0; I <this. length; ++ I)
{
Var value = '';
If (this [I])
{
Value = this [I]. Serialize ();
}
StrArray + = value + ',';
}
If (strArray. charAt (strArray. length-1) = ',')
{
StrArray = strArray. substr (0, strArray. length-1 );
}
StrArray + = ']';
Return strArray;
}
Case 'date ':
{
Return 'new Date ('+ this. getTime () + ')';
}
Case 'boolean ':
Case 'function ':
Case 'number ':
Case 'string ':
{
Return this. toString ();
}
Default:
{
Var serialize = '{';
For (var key in this)
{
If (key = 'serialize') continue;
Var subserialize = 'null ';
If (this [key]! = Undefined)
{
Subserialize = this [key]. Serialize ();
}
Serialize +... the remaining full text>