Форматирование функции фильтра внутри массива с условием if else - PullRequest
2 голосов
/ 21 апреля 2019

В приведенном ниже коде есть объект 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.

Код для ключа и значений фильтра уже существует.

Iпроверено в функции фильтра, если значение содержит массив или нет в зависимости от того, возвращают ли данные фильтра.

И окончательный результат сохраняется в переменной userColl.

В настоящее время я получаюnull на выходе, но я ожидаю первый и третий userList объект;также условие состоит в том, что я не хочу менять usersKey и usersValue.

Заранее спасибо.

Ответы [ 5 ]

1 голос
/ 21 апреля 2019

Вы можете нормализовать свои ограничения и взять массив, потому что его легко итерировать с другим массивом значения ключа и необходимыми значениями в других массивах.

Затем итерируйте 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; }
1 голос
/ 21 апреля 2019

Вы можете использовать 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);
1 голос
/ 21 апреля 2019

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);
1 голос
/ 21 апреля 2019

Вместо использования 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);
0 голосов
/ 21 апреля 2019

Вы можете рассмотреть возможность изменения переменных, которые вы используете в качестве параметров фильтра, на 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;}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...