如何在对象数组上使用 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.isArray
为 false
则为原值,否则 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}
})
我有以下对象数组,其中一些特定键的值可以是字符串或数组。我想按原样获取具有字符串值的键,并从具有数组值的键中删除 "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.isArray
为false
则为原值,否则 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}
})