【问题标题】:javascript filter array in array数组中的javascript过滤器数组
【发布时间】:2016-03-26 16:57:57
【问题描述】:

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

【问题讨论】:

  • 请添加想要的结果。
  • 缺少对您甚至希望此代码执行的操作的描述...请参阅How to Ask。另请注意,else if 条件下不会返回任何内容
  • 你可以用Array.isArray()替换Object.prototype.toString.call( obj ) === '[object Array]')
  • 是的,您的预期输出是 3,但您的实际输出(根据更正后的代码)是 2。您能解释一下您要达到的目标吗?
  • 啊,试图获取键为id 的对象,其值为typeof number。

标签: javascript arrays multidimensional-array filter


【解决方案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>');

【讨论】:

    【解决方案2】:

    你必须修改以下分支:

    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
    }
    

    (取决于你想做什么)

    【讨论】:

    • 第二个变种正是我所期待的!
    【解决方案3】:

    差不多了。在else if 中,您不会返回任何内容。而不是

    obj.filter(filterByID);

    试试return (obj.filter(filterByID).length &gt; 0);

    因为如果递归 filterByID 的结果是一个长度大于 0 的数组,你想将它添加到外部结果中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-28
      • 2020-02-24
      • 2023-03-08
      • 2017-12-18
      • 2011-09-14
      • 2020-05-30
      • 2017-07-19
      • 1970-01-01
      相关资源
      最近更新 更多