Javascript过滤对象内的数组
Posted
技术标签:
【中文标题】Javascript过滤对象内的数组【英文标题】:Javascript filter arrays within an object 【发布时间】:2020-10-21 11:39:33 【问题描述】:假设我有一个具有结构的对象
data =
a : [values: key1: 5, key2: "abc", values: key1: 3, key2: "abc", values: key1: 4, key2: "cde"],
b : [values: key1: 3, key2: "ffe", values: key1: 11, key2: "gga", values: key1: 7, key2: "abc"]
我想提取 key2 == "abc"
所在的元素。
预期输出:
data =
a : [values: key1: 5, key2: "abc", values: key1: 3, key2: "abc"],
b : [values: key1: 7, key2: "abc"]
我尝试关注类似的examples,但未能实现我想要的。
【问题讨论】:
【参考方案1】:使用Object.entries()
将data
的所有键/值对提取为一个数组,map 在每对上,然后在每个值上使用filter
以提取您想要的。
然后您可以使用 Object.fromEntries()
重新加入它
const data =
a : [values: key1: 5, key2: "abc", values: key1: 3, key2: "abc", values: key1: 4, key2: "cde"],
b : [values: key1: 3, key2: "ffe", values: key1: 11, key2: "gga", values: key1: 7, key2: "abc"]
const findKey = 'key2'
const findValue = 'abc'
const newData = Object.fromEntries(Object.entries(data).map(([ key, val ]) =>
[ key, val.filter(( values ) => values?.[findKey] === findValue) ]))
console.log(newData)
如果你还没有看到Optional Chaining,这个...
values?.[findKey] === findValue
等价于
!!values && values[findKey] === findValue
【讨论】:
我的大脑很痛,试图跟随那里发生的所有解构。 虽然这行得通,但这里有太多的解构,你可能会失去流程 @ManosKounelakis 这里只有两个解构,一个数组 ([ key, val ]
) 和一个对象 ( value
)。不确定你认为什么太多?
你真的需要可选链吗?我想如果您尝试访问不存在的第一层的属性,它会返回未定义?
@Ifaruki 以防任何数组条目没有 values
属性。如果他们这样做了,values
将是 undefined
和 values[findKey]
会抛出一个错误【参考方案2】:
简单的 for of 循环遍历键和 filters 数组并直接重新分配属性。 直接改变数据。
使用filter 和destructures key2 对其进行过滤。
const data =
a : [values: key1: 5, key2: "abc", values: key1: 3, key2: "abc", values: key1: 4, key2: "cde"],
b : [values: key1: 3, key2: "ffe", values: key1: 11, key2: "gga", values: key1: 7, key2: "abc"]
for(const k of Object.keys(data))
data[k] = data[k].filter((values: key2)=>key2==='abc')
console.log(data)
添加了对 .length 的检查以修剪具有空数组的键, 并为 key2 设置默认值,因此 values 属性是可选的:
const data =
a : [values: key1: 5, key2: "abc", values: key1: 3, key2: "abc", values: key1: 4, key2: "cde"],
b : [values: key1: 3, key2: "ffe", values: key1: 11, key2: "gga", values: key1: 7, key2: "abc"]
for(const k of Object.keys(data))
(data[k] = data[k].filter((values:key2=)=>key2==='abc'))
.length || delete data[k]
console.log(data)
【讨论】:
【参考方案3】:data =
a : [values: key1: 5, key2: "abc", values: key1: 3, key2: "abc", values: key1: 4, key2: "cde"],
b : [values: key1: 3, key2: "ffe", values: key1: 11, key2: "gga", values: key1: 7, key2: "abc"]
var resp =
for (var key in data)
var local = [];
data[key].forEach(element =>
if(element['values']['key2'] == 'abc')
local.push(element);
)
resp[key] = local;
console.log(resp);
回应
a : [values: key1: 5, key2: "abc", values: key1: 3, key2: "abc"],
b : [values: key1: 7, key2: "abc"]
【讨论】:
【参考方案4】:您可以将对象的属性简化为通过过滤器的属性
const data =
a : [values: key1: 5, key2: "abc", values: key1: 3, key2: "abc", values: key1: 4, key2: "cde"],
b : [values: key1: 3, key2: "ffe", values: key1: 11, key2: "gga", values: key1: 7, key2: "abc"]
;
const results = Object.getOwnPropertyNames(data).reduce((results, key) =>
const filtered = data[key].filter(item => item.values.key2 === 'abc');
if (filtered && filtered.length)
results[key] = filtered;
return results;
, );
console.log(results);
【讨论】:
如果他们想要省略空结果,可能需要与 OP 澄清,但这是一个很好的补充【参考方案5】:由于您需要迭代对象属性,我建议您使用Object.keys(object)
提取它们,您可以在此处找到:
https://developer.mozilla.org/es/docs/Web/javascript/Referencia/Objetos_globales/Object/keys
我建议你这样迭代:
Object.keys(data).forEach(attribute =>
data[attribute] = data[attribute].filter(value => value.values.key2 === 'abc');
)
祝你好运。
【讨论】:
以上是关于Javascript过滤对象内的数组的主要内容,如果未能解决你的问题,请参考以下文章
如何通过猫鼬(javascript)中的多个值查询数组内的对象?
如何在Javascript中选择对象内的数组内的字段[重复]