2017-04-14 182 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