2016-03-29 29 views
3

daha verimli yönlü: Her iki dizideJavaScript - "map" birlikte iki diziler (bazı kullanıcı girişi dayalı bir sunucudan almak) iki nesne diziler var

array1 = [{id:1, name:Bob}, {id:2, name:John}, {id:3, name:Mary}]; 
array2 = [{id:2, field:true},{id:2, field:true}, {id:3, field:false}]; 

kimliklerini birbirlerine karşılık (kullanıcı kimlikleridir). Gerçek hayatta bu diziler çok daha büyük olacaktır (dizi 1'de 8000, dizi2'de 16000'e kadar).

Yapmam gereken şey ön uçta şu anda kullanıcı kimliğini ve alanı gösteren sadece dizi2 bilgisini gösteriyorum. Sorun, ön uç kullanıcının kullanıcı kimliğiyle kimseyi tanımıyor, onların isimleriyle tanıyorlar. Şu gibi görünen nesneler olan bir diziye ihtiyacım var: {id:'',name:'',field:''}.

İlk düşüncem "iki dizi birleştirmek" yeni bir dizi oluşturmak ve etmekti:

var new_array = []; 

for (var i = 0; i < array2.length; i++) { 
    var name = 'Unknown'; 
    for (var j = 0; j < array1.length; j++) { 

    if (array1[j].id === array2[i].id) { 
     name = array1[j].name; 
    } 

    this.new_array.push({ 
     id: array2[i].id, 
     name: name, 
     field: array1[j].field 
    }); 
    } 
} 

Yani ikinci dizisinde ilerleyebilir ve kimliği ilk dizinin kimliği ile eşleşen olmadığını kontrol edin. Eğer ismimi ilk diziden alıyorum ve bu kullanıcının ismidir, böylece kullanıcının adını nasıl alacağım.

Bu çalışma, ancak ön uçta biraz yavaş, bunu yapmak birkaç saniye sürüyor ve çok sayıda öğe varsa kullanıcı deneyimi iyi hissetmiyorsa çok fazla bekleme var. Yapmam gerekeni yapmak için daha verimli bir yol arıyorum.

+1

Örneğinizde 'dizi1''in dizinleri kimlikleriyle tutarlı (eğer kapalı ise 1). Bu gerçek dizilerinizde doğru mu? –

+0

Evet, endeks ve kimliğin ortak hiçbir tarafı yok. Aslında kullanıcı kimliği 8 haneli sayıdır ve dizi1'de sunucudan herhangi bir sırayla döndürülebilirler. – user2924127

+0

Gönderdiğiniz kod, dizi2'nin her değeri için yeni bir değeri 'new_array' ve her biri için dizi1'in her değeri için zorlar. Böylece, "new_array" uzunluğunun "dizi1.length * array2.length" veya örnek numaralarınızı, "8000 * 16000" veya 128 milyon girişlerini kullanması gerekir. Gerçekten böyle mi çalışıyor, yoksa sadece "id" değerini eşleştirerek birleşmek mi istiyorsun? – Pointy

cevap

3

Run tek dizi üzerinden ve girişlere id değerlerini eşleştirmek için bir nesne oluşturmak:

Şimdi
var array2idx = array2.reduce(function(map, value) { 
    map[value.id] = value; 
    return map; 
}, {}); 

basit bir arama ile array2 değerleri bulabilirsiniz:

var new_array = []; 
for (var i = 0; i < array1.length; i++) { 
    var v2 = array2idx[array1[i].id]; 
    if (v2) { 
    new_array.push({ 
     id: v2.id, 
     name: array1[i].name, 
     field: array1[i].field 
    }); 
    } 
} 

ölçüde daha hızlı olmalı O . Dizin nesnesinde bir kimlik aramak neredeyse hiç zaman almaz.

+0

Bu örnek kodun, OP'nin gerçekten istediği şeyin, SQL dizisi gibi bir işlemi iki dizinin arasında yapmak olduğunu varsaydığını unutmayın. "id" özelliğinde. Sorudaki kod çapraz bir ürün yapıyor ama aslında istenen şeyden şüphe duyuyorum. – Pointy

+1

Basitleştirilmiş, bu çözüm orijinal O (n * m) ile karşılaştırıldığında O (n + m) 'dir. –

+1

Bunun için teşekkürler çok daha iyi çalışıyor! – user2924127

İlgili konular