2017-04-14 141 views
1

我已經找了一些數據,如:過濾JSON對象

var items = [ 
{ "id" : 1, 
    "title" : "this", 
    "groups" : [ 
     {"id" : 1, 
     "name" : "groupA"}, 
     {"id" : 2, 
     "name" : "groupB"} 
    ] 
}, 
{ "id" : 2, 
    "title" : "that", 
    "groups" : [ 
     {"id" : 1, 
     "name" : "groupA"}, 
     {"id" : 3, 
     "name" : "groupC"} 
    ] 
}, 
{ "id" : 3, 
    "title" : "other", 
    "groups" : [ 
     {"id" : 3, 
     "name" : "groupC"}, 
     {"id" : 2, 
     "name" : "groupB"} 
    ] 
}] 

我想根據羣ID過濾,但我有麻煩甚至訪問他們 - item.group回報整個對象和其他任何事情(例如item.groups.id)都返回一個null或未定義的值。

有關如何做到這將是偉大的任何幫助。基本上我想過濾數組以包含特定組中的所有項目。

感謝

+0

壞的數據結構。你不應該在每個'item.groups'數組中有組信息。組應該有一個單獨的數組或者是地圖和'item.groups'數組應該只有該組的索引,或者引用到組項目。這將減少JSON的大小,並使數據更容易管理。 – Blindman67

回答

0

試試這個:

group3Items = items.filter(item => item.groups.findIndex(group => group.id==3) > -1) 
+0

我注意到,當我已經粘貼的解決方案。固定:) – hazardous

+1

也結帳[Array.prototype.includes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)。結果變成:'group3Items = items.filter(item => item.groups.includes(group => group.id == 3))'。但請注意,您需要一個polyfill,因爲'includes'是es2017的一個功能 –

+0

謝謝,是的,這就是我選擇findIndex :)的原因。 – hazardous

0

用途:

  1. Array.prototype.map通過
  2. 創建一個新的數組映射數組的新對象中的每一項克隆每個項目使用spread operator *並覆蓋從原廠作出了新的陣列groups鍵L請使用
  3. Array.prototype.filter只保留具有正確id的對象。

*需要一個transpiler如巴貝爾或打字稿雖然

OR

如果你想扁平化結構,那麼你可以使用Array.prototype.reduce的陣列組合。


下面的代碼有兩個輸出:

  1. 一個保持原有結構,但過濾掉不具有的3一個ID組中的項目。
  2. 一個變平的結構和輸出只有一個陣列。

const items = [{ 
 
    "id": 1, 
 
    "title": "this", 
 
    "groups": [{ 
 
     "id": 1, 
 
     "name": "groupA" 
 
     }, 
 
     { 
 
     "id": 2, 
 
     "name": "groupB" 
 
     } 
 
    ] 
 
    }, 
 
    { 
 
    "id": 2, 
 
    "title": "that", 
 
    "groups": [{ 
 
     "id": 1, 
 
     "name": "groupA" 
 
     }, 
 
     { 
 
     "id": 3, 
 
     "name": "groupC" 
 
     } 
 
    ] 
 
    }, 
 
    { 
 
    "id": 3, 
 
    "title": "other", 
 
    "groups": [{ 
 
     "id": 3, 
 
     "name": "groupC" 
 
     }, 
 
     { 
 
     "id": 2, 
 
     "name": "groupB" 
 
     } 
 
    ] 
 
    } 
 
]; 
 

 
const filteredRemovingGroups = items.map(item => ({ 
 
    ...item, 
 
    groups: item.groups.filter(subItem => subItem.id === 3) 
 
})); 
 

 
const filterAndFlatten = items.map(item => 
 
    item.groups.filter(subItem => subItem.id === 3) 
 
).reduce((combinedArr, arr) => [...combinedArr, ...arr], []) 
 

 
console.log('filteredRemovingGroups', filteredRemovingGroups); 
 
console.log('filterAndFlatten', filterAndFlatten);

0

你可以這樣做

var items = [{ 
    "id": 1, 
    "title": "this", 
    "groups": [{ 
    "id": 1, 
    "name": "groupA" 
    }, { 
    "id": 2, 
    "name": "groupB" 
    }] 
}, { 
    "id": 2, 
    "title": "that", 
    "groups": [{ 
    "id": 1, 
    "name": "groupA" 
    }, { 
    "id": 3, 
    "name": "groupC" 
    }] 
}, { 
    "id": 3, 
    "title": "other", 
    "groups": [{ 
    "id": 3, 
    "name": "groupC" 
    }, { 
    "id": 2, 
    "name": "groupB" 
    }] 
}] 

// A filter function to filter out the matched value 
function filterArray(array, val) { 
    return array.filter(function(elem) { 
    return elem.id === val; // filtering by Id 
    }) 
} 

// first filtering the original items array, & will get the object where id is 1 
var obj = filterArray(items, 1); 
//the previous result will return an array, 
//so doing obj[0] which will give the first index. 
//obj[0].groups will be an array again 

var filterGroup = filterArray(obj[0].groups,1) // will be an array which contains the matched group 

DEMO