对象数组:return 只有属性匹配的对象(和子对象)
Array of objects: return only objects (and children) where attribute matches
我有一个包含多个 "levels" 或子项的数组。我想创建一个新的对象数组,其中 archived===false 以便不列出任何存档对象。
所以这个...
var arr = [
{"id":1, "archived":false,"children":[
{"id":1,"archived":true, "subs":[
{"id":1,"archived":true},
{"id":2,"archived":true},
{"id":3,"archived":true}
]},
{"id":2,"archived":false, "subs":[
{"id":1,"archived":false},
{"id":2,"archived":false},
{"id":3,"archived":true}
]}
]},
{"id":2, "archived":true,"children":[
{"id":1,"archived":true, "subs":[
{"id":1,"archived":true},
{"id":2,"archived":true},
{"id":3,"archived":true}
]},
{"id":2,"archived":true, "subs":[
{"id":1,"archived":true},
{"id":2,"archived":true},
{"id":3,"archived":true}
]}
]},
{"id":3, "archived":false,"children":[
{"id":1,"archived":false, "subs":[
{"id":1,"archived":true},
{"id":2,"archived":false},
{"id":3,"archived":true}
]},
{"id":2,"archived":false, "subs":[
{"id":1,"archived":false},
{"id":2,"archived":false},
{"id":3,"archived":false}
]}
]}
];
变成...
var arr = [
{"id":1, "archived":false,"children":[
{"id":2,"archived":false, "subs":[
{"id":1,"archived":false},
{"id":2,"archived":false}
]}
]},
{"id":3, "archived":false,"children":[
{"id":1,"archived":false, "subs":[
{"id":2,"archived":false}
]},
{"id":2,"archived":false, "subs":[
{"id":1,"archived":false},
{"id":2,"archived":false},
{"id":3,"archived":false}
]}
]}
];
我试过 map、reduce、filter 和 grep 的组合...但我可能没有正确的顺序等。我知道我可以循环遍历每个级别,但我无法获得刚刚好。
最好将其包含在 linq.js 可枚举数组或 jQuery.
中
这需要递归。
更改您的代码以包含一个按照此伪代码行工作的函数:
function filterRecursive(array, filterFunction){
for(obj in array){
if(obj.children){
obj.children = filterRecursive(obj.children, filterFunction);
}
obj = filterFunction(obj);
}
}
我没有递归并假设初始对象的深度和结构是固定的解决方案:
var arr = [
{
"id": 1, "archived": false, "children": [
{
"id": 1, "archived": true, "subs": [
{"id": 1, "archived": true},
{"id": 2, "archived": true},
{"id": 3, "archived": true}
]
},
{
"id": 2, "archived": false, "subs": [
{"id": 1, "archived": false},
{"id": 2, "archived": false},
{"id": 3, "archived": true}
]
}
]
},
{
"id": 2, "archived": true, "children": [
{
"id": 1, "archived": true, "subs": [
{"id": 1, "archived": true},
{"id": 2, "archived": true},
{"id": 3, "archived": true}
]
},
{
"id": 2, "archived": true, "subs": [
{"id": 1, "archived": true},
{"id": 2, "archived": true},
{"id": 3, "archived": true}
]
}
]
},
{
"id": 3, "archived": false, "children": [
{
"id": 1, "archived": false, "subs": [
{"id": 1, "archived": true},
{"id": 2, "archived": false},
{"id": 3, "archived": true}
]
},
{
"id": 2, "archived": false, "subs": [
{"id": 1, "archived": false},
{"id": 2, "archived": false},
{"id": 3, "archived": false}
]
}
]
}
];
function checkChildrensForFalse(elements) {
var retVal = [];
for (var eleChildIndex in elements) {
if (elements[eleChildIndex].archived == false) {
var tmpObj = {
'id': elements[eleChildIndex].id,
'archived': elements[eleChildIndex].archived,
'subs': []
}
for (var eleSubIndex in elements[eleChildIndex].subs) {
if (elements[eleChildIndex].subs[eleSubIndex].archived == false) {
tmpObj.subs.push(elements[eleChildIndex].subs[eleSubIndex]);
}
}
if (tmpObj.subs !== []) {
retVal.push(tmpObj);
}
}
}
return retVal;
}
arr = arr.map(function (currentValue, index, array) {
if (currentValue.archived == false) {
var ele = checkChildrensForFalse(currentValue.children);
if (ele !== []) {
return {'id': currentValue.id, 'archived': currentValue.archived, 'children': ele};
}
} else {
return null;
}
}).filter(function (item) {
return item != null
});
/**********
* The result formatted is:
var result = [{
"id": 1, "archived": false,"children": [{
"id": 2, "archived": false, "subs": [
{"id": 1, "archived": false}, {"id": 2, "archived": false}]
}]
}, {"id": 3, "archived": false, "children": [
{"id": 1, "archived": false, "subs": [{"id": 2, "archived": false}]},
{"id": 2, "archived": false, "subs": [{"id": 1, "archived": false}, {"id": 2, "archived": false}, {"id": 3, "archived": false}]
}]
}];
*/
document.write('<p>' + JSON.stringify(arr) + '</p>')
一个精心设计的处理递归的函数可以使 linq.js 变得相当简单。这尤其不一定需要 linq.js,但它保持简单。
function isNotArchived(childrenName, childrenFilter) {
return function (e) {
var filtered = e.Where("!$.archived");
if (childrenName && childrenFilter) {
return filtered.Select(function (c) {
var result = { id: c.id, archived: c.archived };
result[childrenName] = $.Enumerable.From(c[childrenName])
.Let(childrenFilter)
.ToArray();
return result;
});
}
return filtered;
};
}
var filtered = $.Enumerable.From(arr)
.Let(isNotArchived("children",
isNotArchived("subs",
isNotArchived()
)
))
.ToArray();
我有一个包含多个 "levels" 或子项的数组。我想创建一个新的对象数组,其中 archived===false 以便不列出任何存档对象。
所以这个...
var arr = [
{"id":1, "archived":false,"children":[
{"id":1,"archived":true, "subs":[
{"id":1,"archived":true},
{"id":2,"archived":true},
{"id":3,"archived":true}
]},
{"id":2,"archived":false, "subs":[
{"id":1,"archived":false},
{"id":2,"archived":false},
{"id":3,"archived":true}
]}
]},
{"id":2, "archived":true,"children":[
{"id":1,"archived":true, "subs":[
{"id":1,"archived":true},
{"id":2,"archived":true},
{"id":3,"archived":true}
]},
{"id":2,"archived":true, "subs":[
{"id":1,"archived":true},
{"id":2,"archived":true},
{"id":3,"archived":true}
]}
]},
{"id":3, "archived":false,"children":[
{"id":1,"archived":false, "subs":[
{"id":1,"archived":true},
{"id":2,"archived":false},
{"id":3,"archived":true}
]},
{"id":2,"archived":false, "subs":[
{"id":1,"archived":false},
{"id":2,"archived":false},
{"id":3,"archived":false}
]}
]}
];
变成...
var arr = [
{"id":1, "archived":false,"children":[
{"id":2,"archived":false, "subs":[
{"id":1,"archived":false},
{"id":2,"archived":false}
]}
]},
{"id":3, "archived":false,"children":[
{"id":1,"archived":false, "subs":[
{"id":2,"archived":false}
]},
{"id":2,"archived":false, "subs":[
{"id":1,"archived":false},
{"id":2,"archived":false},
{"id":3,"archived":false}
]}
]}
];
我试过 map、reduce、filter 和 grep 的组合...但我可能没有正确的顺序等。我知道我可以循环遍历每个级别,但我无法获得刚刚好。
最好将其包含在 linq.js 可枚举数组或 jQuery.
中这需要递归。
更改您的代码以包含一个按照此伪代码行工作的函数:
function filterRecursive(array, filterFunction){
for(obj in array){
if(obj.children){
obj.children = filterRecursive(obj.children, filterFunction);
}
obj = filterFunction(obj);
}
}
我没有递归并假设初始对象的深度和结构是固定的解决方案:
var arr = [
{
"id": 1, "archived": false, "children": [
{
"id": 1, "archived": true, "subs": [
{"id": 1, "archived": true},
{"id": 2, "archived": true},
{"id": 3, "archived": true}
]
},
{
"id": 2, "archived": false, "subs": [
{"id": 1, "archived": false},
{"id": 2, "archived": false},
{"id": 3, "archived": true}
]
}
]
},
{
"id": 2, "archived": true, "children": [
{
"id": 1, "archived": true, "subs": [
{"id": 1, "archived": true},
{"id": 2, "archived": true},
{"id": 3, "archived": true}
]
},
{
"id": 2, "archived": true, "subs": [
{"id": 1, "archived": true},
{"id": 2, "archived": true},
{"id": 3, "archived": true}
]
}
]
},
{
"id": 3, "archived": false, "children": [
{
"id": 1, "archived": false, "subs": [
{"id": 1, "archived": true},
{"id": 2, "archived": false},
{"id": 3, "archived": true}
]
},
{
"id": 2, "archived": false, "subs": [
{"id": 1, "archived": false},
{"id": 2, "archived": false},
{"id": 3, "archived": false}
]
}
]
}
];
function checkChildrensForFalse(elements) {
var retVal = [];
for (var eleChildIndex in elements) {
if (elements[eleChildIndex].archived == false) {
var tmpObj = {
'id': elements[eleChildIndex].id,
'archived': elements[eleChildIndex].archived,
'subs': []
}
for (var eleSubIndex in elements[eleChildIndex].subs) {
if (elements[eleChildIndex].subs[eleSubIndex].archived == false) {
tmpObj.subs.push(elements[eleChildIndex].subs[eleSubIndex]);
}
}
if (tmpObj.subs !== []) {
retVal.push(tmpObj);
}
}
}
return retVal;
}
arr = arr.map(function (currentValue, index, array) {
if (currentValue.archived == false) {
var ele = checkChildrensForFalse(currentValue.children);
if (ele !== []) {
return {'id': currentValue.id, 'archived': currentValue.archived, 'children': ele};
}
} else {
return null;
}
}).filter(function (item) {
return item != null
});
/**********
* The result formatted is:
var result = [{
"id": 1, "archived": false,"children": [{
"id": 2, "archived": false, "subs": [
{"id": 1, "archived": false}, {"id": 2, "archived": false}]
}]
}, {"id": 3, "archived": false, "children": [
{"id": 1, "archived": false, "subs": [{"id": 2, "archived": false}]},
{"id": 2, "archived": false, "subs": [{"id": 1, "archived": false}, {"id": 2, "archived": false}, {"id": 3, "archived": false}]
}]
}];
*/
document.write('<p>' + JSON.stringify(arr) + '</p>')
一个精心设计的处理递归的函数可以使 linq.js 变得相当简单。这尤其不一定需要 linq.js,但它保持简单。
function isNotArchived(childrenName, childrenFilter) {
return function (e) {
var filtered = e.Where("!$.archived");
if (childrenName && childrenFilter) {
return filtered.Select(function (c) {
var result = { id: c.id, archived: c.archived };
result[childrenName] = $.Enumerable.From(c[childrenName])
.Let(childrenFilter)
.ToArray();
return result;
});
}
return filtered;
};
}
var filtered = $.Enumerable.From(arr)
.Let(isNotArchived("children",
isNotArchived("subs",
isNotArchived()
)
))
.ToArray();