如何在对象数组上使用 Array.protoype.map() 来根据它的值过滤掉一些特定的键?

How to use Array.protoype.map() on array of objects to filter out some specific keys based on it's values?

我有以下对象数组,其中一些特定键的值可以是字符串或数组。我想按原样获取具有字符串值的键,并从具有数组值的键中删除 "NA"。

我试图通过对数组执行 .map 方法来实现相同的目的,检查数据对象中每个键的值的类型,如果是数组,则使用 .filter 删除 "NA"值。

var dataArr = [
    {
     a: 'foo',
     b: [1, 2, "NA", "NA", 3],
     c: ["NA", 6]
    },
    {
     a: 'bar',
     b: ["NA", "NA", "NA"],
     c: []
    }
];
dataArr.map(dataObj => {
    for (let key in dataObj) {
        if (key !== 'a')
            dataObj[key] = dataObj[key].filter(val => { if(val != "NA") return val})
    }
    return dataObj;
});

上面的代码块按预期工作,但我想要一个更好的、面向未来的解决方案。而且,这看起来也很糟糕。

对对象的条目使用 for...of。对于每个条目检查它是否是一个数组。如果是数组过滤器,则赋值给新的对象。如果不是,则分配而不过滤。这不会改变原始数组。

const dataArr = [{"a":"foo","b":[1,2,"NA","NA",3],"c":["NA",6]},{"a":"bar","b":["NA","NA","NA"],"c":[]}]

const result = dataArr.map(dataObj => {
  const filterObject = {};
  
  for (const [key, val] of Object.entries(dataObj)) {
    filterObject[key] = Array.isArray(val) ?
      dataObj[key].filter(val => val != 'NA')
      :
      val;
  }
  
  return filterObject;
});

console.log(result);

您可以使用嵌套的 map()filter()

  • 首先在主数组上使用map()
  • 然后使用Object.entries()
  • 获取每个对象的条目
  • 然后对每个对象的条目使用map()
  • Return 如果 Array.isArrayfalse 则为原值,否则 return 数组的过滤值。
  • 终于用Object.fromEntries()做了一个对象

var dataArr = [
    {
     a: 'foo',
     b: [1, 2, "NA", "NA", 3],
     c: ["NA", 6]
    },
    {
     a: 'bar',
     b: ["NA", "NA", "NA"],
     c: []
    }
];

const res = dataArr.map(x => 
               Object.fromEntries(
                   Object.entries(x)
                     .map(([k,v]) => 
                        [k,Array.isArray(v) ? v.filter(b => b !== "NA") : v])
                     )
               )

console.log(res)

如果您只想更新原始数组,可以使用 forEach 遍历数组。然后使用 for...in and check if it is an array using Array.isArray(). Update the property after filtering 循环每个对象的键,得到 NA

const dataArr = [{a:'foo',b:[1,2,"NA","NA",3],c:["NA",6]},{a:'bar',b:["NA","NA","NA"],c:[]}];

dataArr.forEach(o => {
  for (const key in o) {
    if (Array.isArray(o[key]))
      o[key] = o[key].filter(s => s !== "NA")
  }
})

console.log(dataArr)

如果你想在不改变原始对象的情况下得到一个新数组,你可以像这样使用map

const dataArr = [{a:'foo',b:[1,2,"NA","NA",3],c:["NA",6]},{a:'bar',b:["NA","NA","NA"],c:[]}];

const newArray = dataArr.map(o => {
  const newObj = {};
  
  for (const key in o) {
    if (Array.isArray(o[key]))
      newObj[key] = o[key].filter(s => s !== "NA")
    else
      newObj[key] = o[key]
  }
  
  return newObj;
})

console.log(newArray)

    const dataArr = [{
            a: 'foo',
            b: [1, 2, "NA", "NA", 3],
            c: ["NA", 6]
        },
        {
            a: 'bar',
            b: ["NA", "NA", "NA"],
            c: []
        }
    ];

    const res = dataArr.map((obj) => {
        for(let i in obj){
            if(Array.isArray(obj[i])){
                obj[i] = obj[i].filter(el=>el!=="NA")
            }
        }
        return obj;
    });

    console.log('@>res', res)

我想这将是一个更好的代码重构,请同时提供所需的输出:

dataArr.forEach(object=>{
  for (let value in object){
   let isArr = Object.prototype.toString.call(data) == '[object Array]';
   isArr? object[value] = object[value].filter(val => {return val != "NA"}):null}
 })