2017-10-26 65 views
11

aşağıdaki dizi var:Düz dizi boyutlu bir dizi (JavaScript) multi

var desiredOutput = [{ 
     "CONTAINER": [{ 
      "BODY": [{ 
       "NEWS": [{ 
        "TITLE": [] 
       }] 
      }] 
     }] 
    }]; 

nasıl JavaScript bunu başarabilirsiniz: Aşağıdaki çıktıyı istiyorum

var sampleArray = [ 
    "CONTAINER", 
    "BODY", 
    "NEWS", 
    "TITLE"]; 

?

Zaten özyinelemeli döngü ile denedim ama çalışmıyor, ben tanımsız verir.

dataChange(sampleArray); 
    function dataChange(data) { 
     for (var i = 0; i < data.length; i++) { 
      changeTheArray[data[i]] = data[i + 1]; 
      data.splice(i, 1); 
      dataChange(changeTheArray[data[i]]); 
     } 
    } 

Teşekkür

cevap

3

Bu yapacağım:

const sampleArray = ["CONTAINER", "BODY", "NEWS", "TITLE"]; 
 
const data = []; // Starting element. 
 
let current = data; // Pointer to the current element in the loop 
 

 
sampleArray.forEach(key => {  // For every entry, named `key` in `sampleArray`, 
 
    const next = [];    // New array 
 
    current.push({[key]: next}); // Add `{key: []}` to the current array, 
 
    current = next;    // Move the pointer to the array we just added. 
 
}); 
 

 
console.log(data);

{[key]: next} nispeten yeni sözdizimi. Onlar computed property names konum.

Bu:

const sampleArray = ["CONTAINER", "BODY", "NEWS", "TITLE"]; 
 
const data = []; // Starting element. 
 
let current = data; // Pointer to the current element in the loop 
 

 
sampleArray.forEach(key => current.push({[key]: current = [] })); 
 

 
console.log(data);
: Sen tek astar olarak forEach yeniden yazabiliriz

const a = 'foo'; 
const b = {}; 
b[a] = 'bar'; 

:

const a = 'foo'; 
const b = {[a]: 'bar'}; 

benzer mi

Bu current.push biraz sağduyumuzun çalışır:

  1. yeni eleman itmek Construct. Bu current için yeni bir değer atar.
  2. .push çağrıda edildi referans yeni öğe itin
  3. . Referanscurrent = [] önce currentdeğeri O
    • .
+1

soru soru soranlar ben senin işlevin ikinci satırında dereference önlemek için ek bir geçici değişken için gitmek istiyorum ;-) – Alnitak

+0

dönek hayvanlardır: 'let sonraki = []; current.push ({[key]: sonraki}); current = next' – Alnitak

+1

@Alnitak: Evet, biraz şaşırdım. – Cerbrus

1

Merhaba ben yapılan demo biraz:

var sampleArray = [ 
     "CONTAINER", 
     "BODY", 
     "NEWS", 
     "TITLE" 
    ], 
    generateArray = [], 
    tmp = null; 

for(var i = 0; i < sampleArray.length; i++) { 
    if(tmp===null){ 
    generateArray[sampleArray[i]] = {}; 
    tmp = generateArray[sampleArray[i]]; 
    }else{ 
    tmp[sampleArray[i]] = {}; 
    tmp = tmp[sampleArray[i]]; 
    }   
} 

console.log(generateArray); 
9

Bu tek satırda, soran şeyi yapar ve hiçbir ek değişkenlerle:

let desiredOutput = sampleArray.reduceRight((obj, key) => [ { [key]: obj } ], []); 

reduceRight çağrı, dizinin sağ ucundan başlayarak kademeli bu nesnenin kendisi bir dizi [ ... ] tek giriştir yeni bir nesne { [key] : _value_ } tek anahtar değeri olarak ([] başlangıç ​​değeri ile tohumlanmış) akım verilerini toplar.

+2

Güzel büyücülük ... Bir 'reduce' yöntemi oluşturmak için çalıştı, ama nedeniyle ağacının dibine hareketli akümülatör için çalışmak alamadım ...' reverse' akıllı bir dokunuş: D – Cerbrus

+0

@Xufox evet Siz yorum yaparken kendime bu sonuca ulaşıyordum - orijinal testlerim '.reverse()' bir _in place_ reversal ve test verilerim zaten bozulmuş olduğu gerçeğiyle karıştırıldı. Bu yüzden '.reduceRight' kullanmak orijinal diziyi el değmeden bıraktığından daha iyidir. – Alnitak

+0

@Cerbrus aslında, 'reductionRight()' daha iyidir. DI hiçbir fikri yoktu böyle oldu: 'fakat Alnitak o – Alnitak