N dizilerini birleştirmenin en etkili yolu nedir?


Yanıtlar:


323

İkiden fazla diziyi birleştiriyorsanız, concat()kolaylık ve olası performans için bir yoldur.

var a = [1, 2], b = ["x", "y"], c = [true, false];
var d = a.concat(b, c);
console.log(d); // [1, 2, "x", "y", true, false];

Yalnızca iki diziyi birleştirmek pushiçin, diziye eklenecek öğelerden oluşan birden fazla bağımsız değişkeni kabul eden gerçek, yeni bir dizi üretmeden bir diziden diğerinin sonuna öğeler eklemek için kullanılabilir. Bununla slice()birlikte de kullanılabilir, concat()ancak bunu yapmaktan hiçbir performans avantajı yoktur .

var a = [1, 2], b = ["x", "y"];
a.push.apply(a, b);
console.log(a); // [1, 2, "x", "y"];

ECMAScript 2015 ve sonraki sürümlerde, bu daha da azaltılabilir

a.push(...b)

Bununla birlikte, büyük diziler için (100.000 veya daha fazla üyeden oluşan), bir dizi öğeyi push(ya apply()ECMAScript 2015 forma operatörünü kullanarak veya kullanarak ) geçiren teknik başarısız olabilir. Bu tür diziler için, bir döngü kullanmak daha iyi bir yaklaşımdır. Ayrıntılar için https://stackoverflow.com/a/17368101/96100 adresine bakın.


1
Testinizin bir hataya sahip olabileceğine inanıyorum: a.concat(b)test durumu gereksiz yere dizinin bir kopyasını yapıyor ve asonra atıyor gibi görünüyor .
ninjagecko

1
@ninjagecko: Haklısın. Güncelledim: jsperf.com/concatperftest/6 . Mevcut iki diziyi birleştiren yeni bir dizi oluşturmak için concat(), genellikle daha hızlı görünür . Bir diziyi mevcut varolan bir diziye birleştirmek için push(), gitmenin yolu budur. Cevabımı güncelledim.
Tim Down

16
Ben push.apply yöntemini kullanarak birkaç yeni dizilerle tek bir dizi genişletmek basit concat çağrı üzerinde büyük bir performans avantajı (~ 100x) olduğunu kanıtlayabilirim. V8 / node.js'de tamsayıların kısa listelerinin çok uzun listesiyle uğraşıyorum.
chbrown

1
Daha da özlü bir yol aush (... b);
dinvlad

1
@dinvlad: Doğru, ancak yalnızca ES6 ortamlarında. Cevabıma bir not ekledim.
Tim Down

158
[].concat.apply([], [array1, array2, ...])

düzenleme : verimlilik kanıtı: http://jsperf.com/multi-array-concat/7

edit2 : Tim Supinie yorumlarda bunun yorumlayıcı çağrı yığını boyutunu aşmasına neden olabileceğinden bahseder. Bu belki de js motoruna bağlıdır, ancak en azından Chrome'da "Maksimum çağrı yığını boyutu aşıldı". Test durumda: [].concat.apply([], Array(300000).fill().map(_=>[1,2,3])). (Şu anda kabul edilen cevabı kullanarak da aynı hatayı aldım, bu yüzden bu tür kullanım durumlarını tahmin etmek veya başkaları için bir kütüphane oluşturmak, hangi çözümü seçerseniz seçin, özel testler gerekebilir.)


3
@ c69: en azından Chrome'da tekrar tekrar .push (#, #, ..., #) seçilen cevap kadar etkili görünüyor. jsperf.com/multi-array-concat Tim Down tarafından seçilen cevapta ayrıca bir hata olabilir. Bu bağlantı, sorulan soru olarak birden fazla diziye katılmanın performans karşılaştırmasıdır (sadece 2 değil); birden fazla olası uzunluk test edilir.
ninjagecko

IMO, iyi yapılmış n dizileri "birleştirmek" için en etkili yol
Eric Uldall

Bu cevap, özellikle, önceden bilinmeyen bir dizi diziye sahip olduğunuzda ve bunların birleştirilmiş olmasını istediğinizde, N'nin önceden bilinmediği durumlarda yararlıdır.
jfriend00

3
ES6 ve yayılma operatörleri ile daha da basitleşiyor: [] .concat (... [dizi1, dizi2, ...]) İkinci üç nokta biraz talihsiz. İlk üç yayılma operatörü geliştiricisidir.mozilla.org
tr/docs/Web/JavaScript/Reference/…

Eydrian: Ben kişisel olarak yayma operatörünü önlemeye çalışıyorum çünkü çok verimsiz, ama bunun uygulamanın olgunlaşmamış olması veya es6 belirtiminin semantiği biraz daha ağır kaldırma gerektirdiğinden emin değilim (yani asla daha iyi olmayacak) ). Yine de bu özel durumda herhangi bir kriter çalıştırmadım.
ninjagecko

34

ES2015 (ES6) kullanan kişiler için

Şimdi dizileri birleştirmek için Spread Sözdizimini kullanabilirsiniz:

const arr1 = [0, 1, 2],
      arr2 = [3, 4, 5];

const result1 = [...arr1, ...arr2]; // -> [0, 1, 2, 3, 4, 5]

// or...

const result2 = [...arr2, ...arr1]; // -> [3, 4, 5, 0, 1, 2]

Bu ne kadar verimli? Test ettiğimden, bu nesneleri içeren diziler için çok yavaş, bkz: jsperf.com/array-concat-vs-array-push-vs-array-spread/1
hitautodestruct

28

concat()Yöntem, iki ya da daha fazla dizi birleştirmek için kullanılır. Varolan dizileri değiştirmez, yalnızca birleştirilen dizilerin bir kopyasını döndürür.

array1 = array1.concat(array2, array3, array4, ..., arrayN);

1
Bazen orijinal diziyi değiştirmediği için JavaScript'ten nefret ediyorum. 🙄
Vincent Hoch-Drei

@ VincentHoch-Drei concatözellikle orijinal diziyi değiştirmeden yeni diziler oluşturmak için kullanılır. Güncellemek istiyorsanız array1, kullanmanız gerekirarray1.push(...array2, ...array3, ...array4)
adiga

24

Birden çok dizinin birleştirmesini işlemek için Array.prototype.concat.apply öğesini kullanın:

var resultArray = Array.prototype.concat.apply([], arrayOfArraysToConcat);

Misal:

var a1 = [1, 2, 3],
    a2 = [4, 5],
    a3 = [6, 7, 8, 9];
Array.prototype.concat.apply([], [a1, a2, a3]); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

1
Bunu beğendim! Birleştirilecek değişken sayıda diziyle kolayca çalışır. +1
Joel

14

Sonucu harita / filtre / sıralama vb. Yoluyla boruların ortasındaysanız ve dizi dizisini bitirmek istiyorsanız, reduce

let sorted_nums = ['1,3', '4,2']
  .map(item => item.split(','))   // [['1', '3'], ['4', '2']]
  .reduce((a, b) => a.concat(b))  // ['1', '3', '4', '2']
  .sort()                         // ['1', '2', '3', '4']

14

Birden çok dizi ve ES6 dizisi için şunu kullanın:

Array.prototype.concat(...arr);

Örneğin:

const arr = [[1, 2, 3], [4, 5, 6], [7, 8 ,9]];
const newArr = Array.prototype.concat(...arr);
// output: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

1
Ayrıca, yinelenen öğeleri kullanarak kaldırabilirsiniz newArr = Array.from(new Set(newArr));.
Darius

Bu neden daktilo ile yazılıyor any[]? Yazmak orada - garip.
Simon_Weaver

Bu, daha büyük dizi hacimlerinde aslında oldukça korkunç bir şekilde verimsizdir. jsperf.com/flatten-array-203948 [].concat.apply([], ...arr) büyük hacimlerde çok daha iyi performans gösterir.
Coleman

7

Şimdi kullanarak çoklu dizileri birleştirebiliriz ES6 Spread. concat()Dizileri birleştirmek için kullanmak yerine, birden çok diziyi düzleştirilmiş bir dizide birleştirmek için forma sözdizimini kullanmayı deneyin. Örneğin:

var a = [1,2];
var b = [3,4];
var c = [5,6,7];
var d = [...a, ...b, ...c];
// resulting array will be like d = [1,2,3,4,5,6,7]

5

böyle çözüldü.

let arr = [[1, 2], [3, 4], [5, 6]];
 console.log([].concat(...arr));

Mükemmel çözüm.
nehem

4

Performansı karşılaştırmak için jsperf.com sitesini kullanabilirsiniz . İşte concat bağlantısı .

Arasında karşılaştırma eklendi:

var c = a.concat(b);

ve:

var c = [];
for (i = 0; i < a.length; i++) {
    c.push(a[i]);
}
for (j = 0; j < b.length; j++) {
    c.push(b[j]);
}

İkincisi kromda neredeyse 10 kat daha yavaştır.


Bununla birlikte, Chrome hariç tüm tarayıcılarda push.apply()olduğundan daha hızlı gibi görünen kullanabilirsiniz concat(). Cevabımı gör.
Tim Down


3

Burada, çok sayıda diziyi birleştirebileceğiniz bir işlev var

function concatNarrays(args) {
    args = Array.prototype.slice.call(arguments);
    var newArr = args.reduce( function(prev, next) {
       return prev.concat(next) ;
    });

    return newArr;
}

Misal -

console.log(concatNarrays([1, 2, 3], [5, 2, 1, 4], [2,8,9]));

çıktı olacak

[1,2,3,5,2,1,4,2,8,9]

3

Diziyi Push ile Birleştir :

const array1 = [2, 7, 4];
const array2 = [3, 5,9];
array1.push(...array2);
console.log(array1)

Concat ve Spread operatörünü kullanma :

const array1 = [1,2];
const array2 = [3,4];

// Method 1: Concat 
const combined1 = [].concat(array1, array2);

// Method 2: Spread
const combined2 = [...array1, ...array2];

console.log(combined1);
console.log(combined2);


2

Dizileriniz varsa ve öğeleri tek bir diziye birleştirmek istiyorsanız, aşağıdaki kodu deneyin (ES2015 gerektirir):

let arrOfArr = [[1,2,3,4],[5,6,7,8]];
let newArr = [];
for (let arr of arrOfArr) {
    newArr.push(...arr);
}

console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];

Veya işlevsel programlama yapıyorsanız

let arrOfArr = [[1,2,3,4],[5,6,7,8]];
let newArr = arrOfArr.reduce((result,current)=>{
    result.push(...current);
    return result;
});

console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];

Ya da yayma operatörü olmadan ES5 sözdizimi ile daha da iyi

var arrOfArr = [[1,2,3,4],[5,6,7,8]];
var newArr = arrOfArr.reduce((result,current)=>{
    return result.concat(current);
});
console.log(newArr);
//Output: [1,2,3,4,5,6,7,8];

Eğer hayır bilmiyorsanız bu şekilde kullanışlıdır. kod zamanında diziler.


2

ES6 ile kısaltın.

new Set([].concat(...Array));

Bu , çoklu dizileri birleştirir ve benzersiz kılar ;

Kod üzerinde demo


ama yinelenenleri kaldırır .. yinelenen dizileri kaldırmak istemiyorsanız ne olur?
Krunal Shah

new Set()yinelenen öğeleri kaldırır. Sadece kaldırın. [].concat(...Array)
ronaldtgi

yeni Set ([]. concat (... Array)) kullanmak istiyorum; ama aynı zamanda tek bir ifadede yinelenenleri kaldırmak istiyorum. mümkün mü ?
Krunal Shah

1

burada 'n' bir dizi dizi, belki de bir dizi dizidir. . .

var answer = _.reduce (n, fonksiyon (a, b) {dönüş a.concat (b)})



0

bunu dene:

i=new Array("aaaa", "bbbb");
j=new Array("cccc", "dddd");

i=i.concat(j);

@reggie, ikiniz de aynı kaynaktan kopyaladınız;)
I.devries

hayır Sizinle aynı bağlantıdaki bilgileri kontrol ettim. ilovethecode.com/Javascript/Javascript-Tutorials-How_To-Easy/…
JAiro

Evet ... Sanırım aynı kaynaktan aldık: D
reggie

en azından @JAiro dizi içeriğini değiştirdi. @Reggie olmadı. :)
dogbane

Aynı şey, önemli olan insanların sorunlarını çözmelerine yardımcı olmaktır :)
JAiro

0

N dizileri veritabanından alınmış ve sabit kodlanmamışsa, ES6 kullanarak bunu yapacağım

let get_fruits = [...get_fruits , ...DBContent.fruit];
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.