[英]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()
来做到这一点
map()
on the main array. map()
。 Object.entries()
Object.entries()
获取每个对象的条目 map()
on the entries of each object. map()
。 Array.isArray
is false
otherwise return the filtered value of array. Array.isArray
为false
, Array.isArray
返回值,否则返回数组的过滤后的值。 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.