2013-02-15 102 views
0

我有這個工作代碼,它從JS對象中檢索對象屬性的名稱(不幸的是!)超出了我的範圍。所以我無法改變這個對象的構建方式。但是我想(並且確實)將屬性的名稱(標記爲true)提取爲數組,以便能夠更輕鬆地處理此對象。通過名稱獲得嵌套對象屬性的更優雅方式?

對象:

{ 
    group1: { 
     foo: true, 
     itemFoo: "Name of foo", // This is what I want, because foo is true 
     bar: false, 
     itemBar: "Name of bar", // I dont want this, bar is false 
     // ... 
    }, 
    group2: { 
     baz: true, 
     itemBaz: "Name of baz", // I want this too 
     // ... 
    }, 
    uselessProp1: "not an object", 
    // ... 
} 

工作代碼:

var items = []; 

for (var m in obj) { 
    if (typeof obj[m] == 'object') { 
     for (var n in obj[m]) { 
      if (obj[m][n] === true) { 
       items.push(obj[m]['item' + (n.charAt(0).toUpperCase() + n.slice(1))]); 
      } 
     } 
    } 
} 

我的問題是:沒有人知道實現這個遍歷與underscore.js或普通的node.js或任何其他的更優雅的方式圖書館?我做了_.filter的實驗,但沒有提出解決方案。

+0

這是最好的方式,因爲它是可讀的,因此可維護,易於更改,發現錯誤,不依賴於第三方模塊等。 – 2013-02-15 11:27:46

回答

1

這樣的事情?

var result = []; 
_.chain(obj).filter(_.isObject).each(function(t) { 
    _(t).each(function(val, key) { 
     if(val === true) 
      result.push(t['item' + key.charAt(0).toUpperCase() + key.substr(1)]) 
    }) 
}) 
+1

+1好吧,不是更優雅/可讀,但好點。 – migg 2013-02-15 10:17:51

1

這是解決目前爲止我已經來了:

http://jsfiddle.net/kradmiy/28NZP/

var process = function (obj) { 
var items = []; 

var objectProperties = _(obj).each(function (rootProperty) { 
    // exit from function in case if property is not an object 
    if (!_(rootProperty).isObject()) return; 

    _(rootProperty).each(function (value, key) { 
     // proceed only if property is exactly true 
     if (value !== true) return; 
     var searchedKey = 'item' + (key.charAt(0).toUpperCase() + key.slice(1)); 
     // check that parent has this property... 
     if (rootProperty.hasOwnProperty(searchedKey)) { 
      // ...and push that to array 
      items.push(rootProperty[searchedKey]); 
     } 
    }); 
}); 

    return items; 
}; 
+0

+1 Thx,也不是更優雅/可讀,但有用。 – migg 2013-02-15 10:20:39

+0

使其可讀性的最佳方式不是改進algorythm本身,而是將代碼拆分爲幾個函數調用。所以迭代就像這樣執行:'_(obj).each(objectProperty(filterTrueValues));'。但現在,我無法進一步發揮:) – 2013-02-15 10:49:51

1

我想指出的東西:

Micha’s Golden Rule 
Micha Gorelick, a data scientist in NYC, coined the following rule: 
Do not store data in the keys of a JSON blob. 

你的JSON應該使用:

{//group1 
    groupname:"group1", 
    items :[ 
    {//item1 
     itemcheck:true, 
     itemname:'itemBar' 
    }, 
    ... 
    ] 
}, 
... 

如果將itemname存儲在密鑰中。遍歷JSON時會遇到問題,因爲'itemFoo'會使用'foo'(間接)來獲取它的值。你的數據結構是這裏的問題。搜索你的JSON是棘手的。一旦你遵循規則,你的代碼會自動優雅。

+0

是的,我知道,但正如我在我的問題中指出的那樣,JSON由一個不受我控制的源提供。我會建立這個JSON不同,但我留下來的是將其轉換爲更合理的東西:) – migg 2013-02-15 12:51:25

相關問題