下面的代码中有一个usersData
对象,其中包含usersList
数组。
const usersData = {
usersList: [
{
user: "user1",
langSpeak: ["IND","SPN"],
},
{
user: "user2",
langSpeak: ["IND"],
},
{
user: "user1",
langSpeak: ["IND", "SPN", "JPN"],
},
{
user: "user3",
langSpeak: ["IND", "SPN"],
},
{
user: "user3"
}
]
};
let usersKey = ["user","langSpeak"];
let usersValue = ["user1","IND","SPN"];
let userColl = usersData.usersList.filter(userObj => {
return usersKey.forEach( usersKey => {
if(Array.isArray(userObj[usersKey])){
return userObj[usersKey] && usersValue.forEach(x => {
console.log("x===" + usersKey)
return userObj[usersKey].includes(x)
});
}
if(!Array.isArray(userObj[usersKey])){
console.log(usersKey)
return usersValue.includes(userObj[usersKey]);
}
});
});
console.log(userColl);
有usersKey
和usersValue
。
过滤键和值的代码已经存在。
我检查了过滤器函数的值是否包含数组,具体取决于返回的过滤器数据。
最后的输出存储在userColl
变量中。
当前我的输出为null
,但我期望第一和第三 userList
对象;同样的条件是我不想更改usersKey
和usersValue
。
谢谢。
答案 0 :(得分:1)
应该使用Array.forEach
来检查给定数组中是否存在所需数据,而不是使用Array.every
。
然后使用从every
调用返回的布尔值作为过滤条件来过滤数据。
Array.forEach
不返回任何内容,但Array.filter
期望布尔谓词进行测试,但是在您的代码forEach
中将返回undefined
。
第二个键也应该是langSpeak
而不是code
:
const usersData = {usersList:[{user:"user1",langSpeak:["IND","SPN"]},{user:"user2",langSpeak:["IND"]},{user:"user1",langSpeak:["IND","SPN","JPN"]},{user:"user3",langSpeak:["IND","SPN"]},{user:"user3"}]};
let usersKey = ["user","langSpeak"];
let langValues = ["IND","SPN","JPN"];
let userValues = ["user1"];
let userColl = usersData.usersList.filter(userObj => {
return usersKey.every( usersKey => {
if(Array.isArray(userObj[usersKey])){
return langValues.every(x => {
return userObj[usersKey].includes(x)
});
}
else{
return userValues.every(user => user === userObj[usersKey]);
}
});
});
console.log(userColl);
答案 1 :(得分:1)
您可以使用filter
来过滤数组。使用every
检查所有元素是否都包含某个字符串。
const usersData = {"usersList":[{"user":"user1","langSpeak":["IND","SPN"]},{"user":"user2","langSpeak":["IND"]},{"user":"user1","langSpeak":["IND","SPN","JPN"]},{"user":"user3","langSpeak":["IND","SPN"]},{"user":"user3"}]}
let userFilter = "user1"; //Assign a variable for filtering user
let langFilter = ["IND", "SPN"]; //Assign a variable for filtering language
let result = usersData.usersList.filter(o => o.user == userFilter && o.langSpeak && langFilter.every(e => o.langSpeak.includes(e)));
let finalResult = { //Contruct the final object
usersList: result
}
console.log(finalResult);
如果确实需要使用 usersKey 和 usersValue ,则可以使用reduce
来汇总过滤器,例如:
const usersData = {"usersList":[{"user":"user1","langSpeak":["IND","SPN"]},{"user":"user2","langSpeak":["IND"]},{"user":"user1","langSpeak":["IND","SPN","JPN"]},{"user":"user3","langSpeak":["IND","SPN"]},{"user":"user3"}]}
let usersKey = ["user", "langSpeak"];
let usersValue = ["user1", "IND", "SPN"];
let filter = usersKey.reduce((c, v, i, a) => {
c[v] = i + 1 === a.length ? usersValue.slice(i) : [usersValue[i]];
return c;
}, {});
let result = usersData.usersList.filter(o => Object.entries(filter).every(([k, v]) => v.every(x => o[k].includes(x))));
let finalResult = {
usersList: result
}
console.log(finalResult);
答案 2 :(得分:1)
forEach
不返回任何内容-稍微更改代码以使用every
和some
。我还用三元数对其进行了一些修改:
const usersData = {
usersList: [{
user: "user1",
langSpeak: ["IND", "SPN"],
},
{
user: "user2",
langSpeak: ["IND"],
},
{
user: "user1",
langSpeak: ["IND", "SPN", "JPN"],
},
{
user: "user3",
langSpeak: ["IND", "SPN"],
},
{
user: "user3"
}
]
};
let usersKey = ["user", "langSpeak"];
let usersValue = ["user1", "IND", "SPN"];
let userColl = usersData.usersList.filter(userObj => usersKey.every(k => Array.isArray(userObj[k]) ? usersValue.some(v => userObj[k].includes(v)) : usersValue.includes(userObj[k])));
console.log(userColl);
答案 3 :(得分:1)
您可以规范化约束并获取一个数组,因为使用另一个键值数组和其他数组中的所需值很容易迭代。
然后迭代constraints
并检查对象中的值是否为数组。根据此检查,迭代值或进行一次检查。
var usersList = [{ user: "user1", langSpeak: ["IND", "SPN"] }, { user: "user2", langSpeak: ["IND"] }, { user: "user1", langSpeak: ["IND", "SPN", "JPN"] }, { user: "user3", langSpeak: ["IND", "SPN"] }, { user: "user3" }],
constraints = [
["user", "user1"],
["langSpeak", "IND", "SPN"]
],
result = usersList.filter(o => constraints.every(([key, ...values]) => Array.isArray(o[key])
? values.every(v => o[key].includes(v))
: values.includes(o[key])
));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 4 :(得分:0)
您可以考虑将用作过滤器参数的变量更改为object
或Map()。
请注意,使用变量的方法在某些情况下可能会出现问题,例如,如果某些用户名为IND
,会发生什么情况。您如何知道数组usersValue
的某些元素与过滤属性user
或属性langSpeak
有关?
如果使用对象,则可以这样进行:
const usersData = {
usersList: [
{user: "user1", langSpeak: ["IND","SPN"]},
{user: "user2", langSpeak: ["IND"]},
{user: "user1", langSpeak: ["IND", "SPN", "JPN"]},
{user: "user3", langSpeak: ["IND", "SPN"]},
{user: "user3"}
]
};
let filterObj = {
"user": ["user1"],
"langSpeak": ["IND", "SPN"]
};
let userColl = usersData.usersList.filter(userObj =>
{
return Object.entries(filterObj).every(([k, v]) =>
{
let uVal = userObj[k];
if (Array.isArray(uVal))
return v.every(x => uVal.includes(x));
else
return v.includes(uVal);
});
});
console.log(userColl);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}