简体   繁体   English

如何在对象数组上使用Array.protoype.map()来基于其值过滤掉某些特定键?

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

I have the following array of objects, in which some specific keys have a value which is either a string or an array. 我有以下对象数组,其中某些特定键的值可以是字符串或数组。 I want to get the keys with string values as it is and remove "NA" from keys with array values. 我想按原样获取具有字符串值的键,并从具有数组值的键中删除“ NA”。

I am trying to achieve the same by doing .map method on the array, check the type of the value of each key in the data object, if an array then use .filter to remove the "NA" values. 我试图通过在数组上执行.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;
});

The above block of code works as expected but I want a better and future-proof solution. 上面的代码块按预期工作,但是我想要一个更好的,面向未来的解决方案。 Moreover, this looks bad too. 而且,这看起来也很糟糕。

You can do that using nested map() and filter() 您可以使用嵌套的map()filter()来做到这一点

  • First of all use map() on the main array. 首先在主数组上使用map()
  • Then get the entries of each object using Object.entries() 然后使用Object.entries()获取每个对象的条目
  • Then use map() on the entries of each object. 然后在每个对象的条目上使用map()
  • Return the value as it is if the Array.isArray is false otherwise return the filtered value of array. 如果Array.isArrayfalseArray.isArray返回值,否则返回数组的过滤后的值。
  • Finally use Object.fromEntries() to make an object. 最后使用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) 

If you just want to update the original array, you could loop through the array using forEach . 如果只想更新原始数组,则可以使用forEach遍历该数组。 Then loop through each object's keys using for...in and check if it is an array using Array.isArray() . 然后使用for...in遍历每个对象的键for...in并使用Array.isArray()检查它是否为数组。 Update the property after filtering out the NA value 滤除 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) 

If you want to get a new array without mutating the original objects, you can use map like this: 如果要获得一个新的数组而不改变原始对象,则可以使用如下所示的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) 

Use for...of on the object's entries. for...of对象的条目。 For each entry check if it's an array. 对于每个条目,检查它是否为数组。 If it's an array filter, and then assign to the new object. 如果是数组过滤器,则分配给新对象。 If not, assign without filtering. 如果不是,则分配而不进行过滤。 This will not mutate the original array. 这不会改变原始数组。

 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); 

  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) 

I guess this will be a better code refactor,pls provide with the desired output also: 我想这将是一个更好的代码重构,请提供所需的输出:

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}
 })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 通过在另一个数组中定义的特定值和键过滤出对象数组 - Filter out array of objects by specific values and keys defined in another array 如何根据对象数组中的值过滤键 - how to filter keys based on values in a array of objects NodeJS - 使用 Array.protoype.map() 从异步函数返回单个状态代码以将多个文件保存在数据库中的不同位置 - NodeJS - Return a single status code from an async function using Array.protoype.map() to save multiple files in different locations in a database 如何从数组中过滤出多个特定的键和值 - How to filter out multiple specific keys and values from an array 如何过滤 object 的数组并根据另一个数组过滤掉值? 过滤应该基于键而不是值 - How to filter array of object and filter out values based on another array? Filtering should happen based on keys not values 如何根据某些字段过滤对象数组? - How to filter an array of objects, based on some fields? 如何过滤数组并从中替换一些值 - How to filter an Array and Replace some values out of it 使用 reactjs 键根据单独的 object 值过滤对象数组 - filter array of objects based on separate object values by keys using reactjs 基于单独的对象键、值过滤对象数组 - filter array of objects based on separate object keys, values 对象数组,用0过滤掉值 - Array of objects, filter out values with 0
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM