2017-08-24 59 views
1

假設我有一個深度-N的對象,如:使用Javascript - 遍歷像對象樹,並添加一個關鍵

food = { 
    'Non-Animal': { 
     'Plants' : { 
      'Vegetables': { 
       ... 
      }    
     }, 
      'Minerals' : { 
       ... 
      } 
     }, 
    'Animal': { 
     ... 
    } 
} 

而且我想在這個對象添加分類「水果」,但我要搜索「植物」的對象,然後添加它。所以我不想在一個聲明中做:

food['Non-Animal']['Plants']['Fruits'] = {}; 

因爲我想先查找它所屬的地方。

如何在遍歷對象時將水果類別添加到對象?我到目前爲止是:

addCategory(food, category, parent); 

function addCategory(obj, category, parent_name) { 
    for (var key in obj) { 
     if (key == parent_name) { 
      obj[key][category] = {}; 
     } 
     var p = obj[key]; 
     if (typeof p === 'object') { 
      addCategory(p, category, parent); 
     } else { 

     } 
    } 
} 

我該如何解決這個例程做到這一點或有沒有更好的方式來做到這一點?

+0

您可以檢查[這](https://stackoverflow.com/a/39300560/4543207) – Redu

+0

注意使用'typeof運算p === object''因爲如果' p'是任何類型的對象,比如'array',這是對的。 –

回答

0

看起來很好。然而,你可能要添加道具之後終止:

function addCategory(obj, category, parent_name) { 
    for (var key in obj) { 
     if (key == parent_name){ 
     return obj[key][category] = {}; 
     } 
     var p = obj[key]; 
     if (typeof p === 'object') { 
     if(addCategory(p, category, parent)) return true; 
     } 
    } 
} 
1

如果我正確認識你,我想你會想你的函數定義,把你要經過的路徑的個人名稱的可變參數參數並在必要時創建。

使用.reduce()這使得它很容易。

const food = { 
 
    'Non-Animal': { 
 
    'Plants': { 
 
     'Vegetables': {} 
 
    }, 
 
    'Minerals': {} 
 
    }, 
 
    'Animal': {} 
 
} 
 

 
console.log(addCategory(food, "Non-Animal", "Plants", "Fruits")); 
 
console.log(addCategory(food, "Non-Animal", "Minerals", "Gold")); 
 

 
function addCategory(obj, ...path) { 
 
    return path.reduce((curr, name) => { 
 
    if (!curr) return null; 
 
    if (!curr[name]) return (curr[name] = {}); 
 
    return curr[name]; 
 

 
    // More terse but perhaps less readable 
 
    // return curr ? curr[name] ? curr[name] : (curr[name]={}) : null; 
 
    }, obj); 
 
} 
 

 
console.log(JSON.stringify(food, null, 2));

0

我只看到一個錯誤:addCategory的遞歸調用無法找到父變量,因爲它被稱爲在你的範圍PARENT_NAME。

var food = { 
 
    'Non-Animal': { 
 
    'Plants' : { 
 
     'Vegetables': { 
 
     } 
 
    }, 
 
    'Minerals' : {} 
 
    }, 
 
    'Animal': {} 
 
} 
 

 
function addCategory(obj, category, parent_name) { 
 
    for (var key in obj) { 
 
    if (key == parent_name){ 
 
     obj[key][category] = {}; 
 
    } 
 
    var p = obj[key]; 
 
    if (typeof p === 'object') { 
 
     addCategory(p, category, parent_name); 
 
    } else { 
 

 
    } 
 
    } 
 
} 
 

 
console.log(food); 
 
addCategory(food, 'Fruits', 'Plants'); 
 
console.log(food);

0

可以使用減少創建功能,將採取密鑰字符串對象,你要分配給一些嵌套對象的值。

var food = {"Non-Animal":{"Plants":{"Vegetables":{}},"Minerals":{}},"Animal":{}} 
 

 
function add(key, value, object) { 
 
    key.split('.').reduce(function(r, e, i, arr) { 
 
    if(r[e] && i == arr.length - 1) Object.assign(r[e], value); 
 
    return r[e] 
 
    }, object) 
 
} 
 

 
add('Non-Animal.Plants', {'Fruits': {}}, food) 
 
console.log(food)