【问题标题】:filter array of objects by another true flagged subkey object通过另一个真正的标记子键对象过滤对象数组
【发布时间】:2019-09-11 07:49:06
【问题描述】:

我正在尝试通过此处示例的另一个对象过滤对象列表

// the list need to be filtered 
const list  = [
  {
    "id": 1,
    "name": "Loraine Mueller",
    "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/BroumiYoussef/128.jpg",
    "status": "offline",
    "language": "German",
    "rating": 4,
    "reviews": 4308
  },
  {
    "id": 2,
    "name": "Katarina Kilback",
    "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/dvdwinden/128.jpg",
    "status": "online",
    "language": "German",
    "rating": 5,
    "reviews": 8484
  }
]
const filterBy = {
 status: {
  online: true,
  offline: false
 },
 language: {
  english: true,
  german: false
 }
}

实现 _filterList(list, filterBy) 的想法:返回带有在线和德语项目的过滤列表

我尝试了什么

const _filter = (rows, filterBy) => {
  let result = [...rows];
  Object.keys(filterBy)
    .map(key => result = [...result.filter(row => filterBy[key].includes(row[key]))]);
  return result;
}

【问题讨论】:

  • 请添加想要的结果。过滤器中的true/false是什么意思?
  • 请指定您想要的过滤器。
  • 真实值,即 ["german"] 和 ["online"]
  • 您要使用filterByfilters 还是两者都使用,它们如何连接到resutl 以及彼此?请添加想要的结果。
  • 您的 sn-p 与您的规格不符,并混淆了答案。请删除或编辑以符合规范。

标签: javascript arrays ecmascript-6 filter


【解决方案1】:

假设您想要给定过滤器键是列表中任何值的结果,filter/every/includes 的组合可以解决问题:

const list = [
  {
    id: 1,
    name: "Loraine Mueller",
    status: "offline",
    language: "German",
    rating: 4,
    reviews: 4308,
  },
  {
    id: 2,
    name: "Katarina Kilback",
    status: "online",
    language: "German",
    rating: 5,
    reviews: 8484,
  },
];

function filterBy(list, filters) {
  return list.filter(ent =>
    Object.keys(filters).every(filterKey =>
      filters[filterKey].includes(ent[filterKey]),
    ),
  );
}

console.log(
  filterBy(list, {
    status: ["online"],
    language: ["German"],
  }),
);

仅输出 Katarina。

编辑:根据评论,我们还需要将过滤器对象转换成这个形状。没问题。

function transformFilters(filterBy) {
  const transformedFilters = {};
  for (var key in filterBy) {
    const values = [];
    for (var value in filterBy[key]) {
      if (filterBy[key][value]) {
        values.push(value);
      }
    }
    if (values.length) {
      transformedFilters[key] = values;
    }
  }
  return transformedFilters;
}

console.log(
  transformFilters({
    status: {
      online: true,
      offline: false,
    },
    language: {
      english: true,
      german: false,
    },
  }),
);

输出

{ status: [ 'online' ], language: [ 'english' ] }

【讨论】:

  • 过滤器对象应该是这样的`状态:{在线:真,离线:假},语言:{英语:假,德语:真}`
【解决方案2】:

我使用ruleOut 函数根据特定的不需要的属性值过滤对象。我想把我的方法留在这里。

function ruleOut(arr, filterObj, applyAllFilters=true) {    
    return arr.filter( row => {            
        for (var field in filterObj) {
            var val = row[field];
            if (val) {                    
                if (applyAllFilters && filterObj[field].indexOf(val) > -1) return false;                
                else if (!applyAllFilters) {                        
                    return filterObj[field].filter(function(filterValue){ 
                        return (val.indexOf(filterValue)>-1);
                    }).length == 0;                 
                }
            }
        }
        return true;
    });
}

假设你有一个这样的演员列表:

let actors = [
  {userName:"Mary", job:"star", language:"Turkish"},
  {userName:"John", job:"actor", language:"Turkish"},
  {userName:"Takis", job:"star", language:"Greek"},
  {userName:"Joe", job:"star", language:"Turkish"},
  {userName:"Bill", job:"star", language:"Turkish"}
];

并且您想查找所有被评为好莱坞明星的演员,他们的国籍不应该是“英国”、“意大利”、“西班牙”、“希腊”之一,而且他们的名字不能是“玛丽”,“乔”。 Bizzar的例子,我知道!无论如何,有了这组条件,您将创建以下对象:

let unwantedFieldsFilter= { 
  userName: ['Mary', 'Joe'],    
  job: ['actor'],   
  language: ['English', 'Italian', 'Spanish', 'Greek']  
};

好的,现在如果你ruleOut(actors, unwantedFieldsFilter) 你只会得到

[{用户名:“比尔”,工作:“明星”,语言:“土耳其语”}]

比尔是你的人,因为他的名字不是“玛丽”、“乔”之一,他的国籍不包括在 ['English'、'Italian'、'Spanish'、'Greek'] 中,而且他是一个明星!

我的方法中有一个选项,即applyAllFilters,默认为true。 如果您尝试将此参数设置为 false 的 ruleOut,则将用作“OR”过滤而不是“AND”。 示例:ruleOut(actors, {job:["actor"], language:["Italian"]}, false) 会为您找到所有不是演员或意大利人的人:

[{用户名:“玛丽”,工作:“明星”,语言:“土耳其语”},
{用户名:“Takis”,工作:“star”,语言:“希腊语”},
{用户名:“乔”,工作:“明星”,语言:“土耳其语”},
{userName:“Bill”,工作:“star”,语言:“Turkish”}]

【讨论】:

    猜你喜欢
    • 2021-10-30
    • 2019-05-05
    • 1970-01-01
    • 2019-07-18
    • 1970-01-01
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多