2013-09-23 19 views
6

Nitelik adını tam olarak korurken, N özelliklerinin listesini temel alarak eksiksiz bir varyant kümesi oluşturmam gerekiyor.javascript'te nesnelerin kartezyen çarpımı

var input = [ 
    { 'colour' : ['red', 'green'] }, 
    { 'material' : ['cotton', 'wool', 'silk'] }, 
    { 'shape' : ['round', 'square', 'rectangle'] } 
]; 

var expected = [ 
    { 'colour': 'red', 'material': 'cotton', 'shape': 'round' }, 
    { 'colour': 'red', 'material': 'cotton', 'shape': 'square' }, 
    { 'colour': 'red', 'material': 'cotton', 'shape': 'rectangle' }, 
    { 'colour': 'red', 'material': 'wool', 'shape': 'round' }, 
    { 'colour': 'red', 'material': 'wool', 'shape': 'square' }, 
    { 'colour': 'red', 'material': 'wool', 'shape': 'rectangle' }, 
    { 'colour': 'red', 'material': 'silk', 'shape': 'round' }, 
    { 'colour': 'red', 'material': 'silk', 'shape': 'square' }, 
    { 'colour': 'red', 'material': 'silk', 'shape': 'rectangle' }, 
    { 'colour': 'green', 'material': 'cotton', 'shape': 'round' }, 
    { 'colour': 'green', 'material': 'cotton', 'shape': 'square' }, 
    { 'colour': 'green', 'material': 'cotton', 'shape': 'rectangle' }, 
    { 'colour': 'green', 'material': 'wool', 'shape': 'round' }, 
    { 'colour': 'green', 'material': 'wool', 'shape': 'square' }, 
    { 'colour': 'green', 'material': 'wool', 'shape': 'rectangle' }, 
    { 'colour': 'green', 'material': 'silk', 'shape': 'round' }, 
    { 'colour': 'green', 'material': 'silk', 'shape': 'square' }, 
    { 'colour': 'green', 'material': 'silk', 'shape': 'rectangle' } 
]; 

etrafında diziler kartezyen ürünler için algoritmaların çok var ama anahtarları korur nesneler için bulmak için görünmüyor olabilir.

Performans, her özellik için bir düzineden fazla değer olmayacağı için büyük bir endişe değildir. Siparişin tam olarak expected ile eşleşmesi gerekmez.

Ben listeler için standart algoritmalar dayalı bir başlangıç ​​girişimini yaptık ama mücadele ediyorum: Eğer ' 'i' küresel bir var bir konudur' kurtulmak kez

function cartesianProduct(input, current) { 
    if (!input || input.length < 1) { 
     return []; 
    } 

    var head = input[0]; 
    var tail = input.slice(1); 
    var output = []; 

    for (var key in head) { 
     for (var i = 0; i < head[key].length; i++) { 
      if (typeof current == 'undefined') { 
       var current = {}; 
      } 

      current[key] = head[key][i]; 
      var productOfTail = cartesianProduct(tail, current); 
      output.push(current); 
      console.log(current); 
     } 
    } 

    return output; 
} 

console.log(cartesianProduct(input)); 
+0

([benzer bir soru burada istendi] http://stackoverflow.com/questions/12303989/cartesian-product-of-multiple-arrays-in: örneğin bu kod ile sonuç alabilirsiniz -javascript) – Keithamus

+0

kodunuzda büyük bir sorun var: Ben bir var olarak ilan etmeyin, bu yüzden global bir varyans olarak kabul edilir, dolayısıyla değişiklik iç fonksiyon çağrıları d ... – GameAlchemist

cevap

4

, seni

var input = [ 
    { 'colour' : ['red', 'green'] }, 
    { 'material' : ['cotton', 'wool', 'silk'] }, 
    { 'shape' : ['round', 'square', 'rectangle'] } 
]; 

function cartesianProduct(input, current) { 
    if (!input || !input.length) { return []; } 

    var head = input[0]; 
    var tail = input.slice(1); 
    var output = []; 

    for (var key in head) { 
     for (var i = 0; i < head[key].length; i++) { 
      var newCurrent = copy(current);   
      newCurrent[key] = head[key][i]; 
      if (tail.length) { 
       var productOfTail = 
         cartesianProduct(tail, newCurrent); 
       output = output.concat(productOfTail); 
      } else output.push(newCurrent); 
     } 
    }  
    return output; 
} 

function copy(obj) { 
    var res = {}; 
    for (var p in obj) res[p] = obj[p]; 
    return res; 
} 


console.log(cartesianProduct(input)); 
+0

Bunun için, çıkış dizisine akım itme ile ilgili bir sorun olduğunu biliyordum ama nedenini çözemedim. –

+0

Rica ederim. Hepiniz anlayacağınız gibi, kopyalama olmadan, her bir özyinelemeli aramada tek bir nesneyi değiştirmeye devam ediyorsunuz, dolayısıyla ürün çalışmıyor. – GameAlchemist