我有以下基于docs
的代码var arr = [
{ id: 15 },
{ x: [{ id: 777 }, { id: 'xx' }, { notidproperty: 987 }]},
{ id: 1111 }
];
function filterByID(obj) {
if ('id' in obj && typeof(obj.id) === 'number' && !isNaN(obj.id)) {
return true;
} else if (Object.prototype.toString.call(obj) === '[object Array]') { //obj type is Object, not Array
obj.filter(filterByID);
} else {
return false;
}
}
var arrByID = arr.filter(filterByID);
console.log('expected length = 3, actual length = ' + arrByID.length);
console.log(arrByID);
如何过滤'arr'数组?有没有其他技术可以获得正确的结果?
编辑:预期结果是具有数字值
的id属性的对象的过滤数组因此预期Id值为15,777,1111
答案 0 :(得分:1)
我建议使用Array#reduce()
代替Array#filter()
,因为您需要一个平面数组来计算结果。
我使用isFinite
检查id
。
function rr(r, a) {
Object.keys(a).forEach(function (k) {
if (Array.isArray(a[k])) {
r = r.concat(a[k].reduce(rr, []));
} else {
isFinite(a.id) && r.push(a);
}
});
return r;
}
var arr = [{ id: 15 }, { x: [{ id: 777 }, { id: 'xx' }, { notidproperty: 987 }] }, { id: 1111 }],
result = arr.reduce(rr, []);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
答案 1 :(得分:0)
几乎就在那里。在else if
中,您不会返回任何内容。而不是
obj.filter(filterByID);
尝试return (obj.filter(filterByID).length > 0);
因为如果递归filterByID的结果是长度大于0的数组,则要将其添加到外部结果。
答案 2 :(得分:0)
您必须修改以下分支:
if (Object.prototype.toString.call(obj) === '[object Array]') { //obj type is Object, not Array
obj.filter(filterByID);
}
这仅过滤但不返回任何结果。并且此处不会处理具有Array类型的x属性的对象。所以:
if(obj.x && Array.isArray(obj.x)){
return obj.x.filter(filterByID).length>0
}
或者:
if(obj.x && Array.isArray(obj.x)){
obj.x = obj.x.filter(filterByID)
return true
}
(取决于你想做什么)