数组中的javascript过滤器数组

时间:2016-03-26 16:57:57

标签: javascript arrays multidimensional-array filter

我有以下基于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

3 个答案:

答案 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
}

(取决于你想做什么)