如何解决按条件和对象属性类型过滤数组
我有一个对象数组,我只想返回对象中每种类型的前2个结果。类型是可变的。我也不知道我会拥有多少种类型。
例如,我有这个数组:
var obj = [
{
"number": 1,"type": "one"
},{
"number": 2,{
"number": 3,{
"number": 4,{
"number": 5,{
"number": 1,"type": "two"
},{
"number": 6,"type": "two"
}
];
在此示例中,我们有一个简单的示例:type和type:2。类型可以是任何东西,数量可以是许多。
我希望将其退回:
var obj = [
{
"number": 1,"type": "one"
} {
"number": 1,"type": "two" // <-- Could be several more types
}
];
我知道我可以使用过滤器来获取整个数组的结果,但是我希望对每种变量类型都执行此操作。
var result = obj.filter((val,i)=>i<3);
解决方法
如果数组不是太大,则可以使用这种 O(n)
方法。
基本上,这种方法通过属性type
对对象进行分组,然后使用函数Array.prototype.slice
提取前两个对象,最后将所需的输出构建为数组。
let arr = [{ "number": 1,"type": "one"},{ "number": 2,{ "number": 3,{ "number": 4,{ "number": 5,{ "number": 1,"type": "two"},{ "number": 6,{"number": 3,"type": "three"}],result = Object.values(arr.reduce((a,{number,type}) => {
(a[type] || (a[type] = [])).push({number,type});
return a;
},{})).map(a => a.slice(0,2)).reduce((a,e) => a.concat(e),[]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
,
使用显式循环执行此操作相对简单-但我个人认为使用reduce
方法会更好:
var result = obj.reduce((acc,nextObj) => {
const withSameType = acc.filter(({ type}) => type === nextObj.type);
if (withSameType.length < 2) {
return [...acc,nextObj];
} else {
return acc;
}
},[]);
,
一种方法是只使用一个对象来跟踪您已经从数组中检索到的“类型”的数量。然后,您可以仅过滤条件(原则上与@RobinZigmond的回答没有太大不同,但以这种方式查看可能会有所帮助)。
let arr = [{"number": 1,{"number": 2,{"number": 4,{"number": 5,{"number": 1,{"number": 6,"type": "two"}];
let counter = {};
let filtered = arr.filter((obj) => {
let t = obj['type'];
if (!counter[t]) {
counter[t] = 0;
}
if (counter[t] < 2) {
counter[t] += 1;
return obj;
}
});
console.log(filtered);
// [{number: 1,type: "one"},{number: 2,{number: 1,type: "two"},type: "two"}]
,
您可以使用Map
来跟踪每个type
的计数,并返回每个数字的前两个数字:
const obj = [{number:1,type:'one'},{number:2,{number:3,{number:4,{number:5,{number:1,type:'two'},{number:6,type:'two'}];
const map = new Map();
const result = obj.filter(({ type }) => {
const count = map.has(type) ? map.get(type) : 0;
map.set(type,count + 1);
return count < 2;
});
console.log(result);
,
您可以将它们分组为对象的键,然后使用Object.values和flat提取子数组。
var obj = [{
"number": 1,"type": "one"
},{
"number": 2,{
"number": 3,{
"number": 4,{
"number": 5,{
"number": 1,"type": "two"
},{
"number": 6,"type": "three"
},"type": "three"
}
];
const grouped = obj.reduce((acc,x,i) => {
const key = Object.entries(x).find(([a,b]) => a === 'type')[1];
if (acc[key] && acc[key].length === 2) {
return acc;
}
acc[key] = acc[key] ? [...acc[key],x] : [x];
return acc;
},{})
const result = Object.values(grouped).flat()
console.log(result)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。