-1

我有以下数据数组,我想按公司名称/名称过滤。过滤器公司名称可以是一个或多个。

data = [
   {
      "company":{
         "name":"Company 1",
         "symbol":"one"
      },
      "description":"test",
      "status":"Pending"
   },
   {
      "company":{
         "name":"Company 2",
         "symbol":"two"
      },
      "description":"test",
      "status":"Pending"
   },
   {
      "company":{
         "name":"Company 3",
         "symbol":"three"
      },
      "description":"test",
      "status":"Pending"
   }
]
filter = ["Company 1", "Company 3"]

预期结果

[
   {
      "company":{
         "name":"Company 1",
         "symbol":"one"
      },
      "description":"test",
      "status":"Pending"
   },
   {
      "company":{
         "name":"Company 3",
         "symbol":"three"
      },
      "description":"test",
      "status":"Pending"
   }
]

尝试了以下

  selectedCompaniesEvent() {
    const fn = (arr, filters) => {
      const filtersArr: any = Object.entries(filters);

      return arr.filter((o, index) =>
        filtersArr.every(([key, values]) =>
          values.includes(o[index].company[key])
        )
      );
    };
    
    const result = fn(data, filter);
    console.log(result);
  }

我尝试按照此处的解决方案进行操作,因为我的数据数组是嵌套的,它似乎不起作用。任何帮助将不胜感激!

4

4 回答 4

2

如果数组company.name中存在,您可以过滤结果filter

const data = [
  {
    company: {
      name: "Company 1",
      symbol: "one",
    },
    description: "test",
    status: "Pending",
  },
  {
    company: {
      name: "Company 2",
      symbol: "two",
    },
    description: "test",
    status: "Pending",
  },
  {
    company: {
      name: "Company 3",
      symbol: "three",
    },
    description: "test",
    status: "Pending",
  },
];

const filter = ["Company 1", "Company 3"];

const result = data.filter((obj) => filter.includes(obj.company.name));
console.log(result);

于 2021-07-07T03:01:29.923 回答
1

因为你有filter一个数组,数据也有一个数组,如果你的过滤器变大,那么 O(n 2 ) 复杂性可能会受到伤害。更快的解决方案是将过滤器转换array为 a map,以获得恒定的时间访问,例如-

const filter = ["Company 1", "Company 3"]
const filterMap = new Map()

filter.forEach((company) => {
  filterMap.set(company, 'true')
})

const data = [
   {
      "company":{
         "name":"Company 1",
         "symbol":"one"
      },
      "description":"test",
      "status":"Pending"
   },
   {
      "company":{
         "name":"Company 2",
         "symbol":"two"
      },
      "description":"test",
      "status":"Pending"
   },
   {
      "company":{
         "name":"Company 3",
         "symbol":"three"
      },
      "description":"test",
      "status":"Pending"
   }
]

const result = data.filter((elem) => {
  if (filterMap.get(elem.company.name)) {
    return elem    
  }
})

console.log(result)

于 2021-07-07T03:07:34.057 回答
1

您的方法中的问题:

const fn = (arr, filters) => {
  // entries of an array will return index, value pairs
  // Object.entries(['a','b']) => [[0, 'a'], [1, 'b']]
  const filtersArr: any = Object.entries(filters);

  return arr.filter((o, index) =>
    // every is not suitable based on the expected output as you want elements that satisfy atleast one of the filters but not all
    filtersArr.every(([key, values]) =>
      // o[index] is wrong as o will already hold the object in each iteration
      // key will be a number but it should be a string like 'name'
      values.includes(o[index].company[key])
    )
  );
};

替代

const fn = (arr, filters) => {
  return arr.filter(el => filters.includes(el.company.name))
};

const data = [{
    "company": {
      "name": "Company 1",
      "symbol": "one"
    },
    "description": "test",
    "status": "Pending"
  },
  {
    "company": {
      "name": "Company 2",
      "symbol": "two"
    },
    "description": "test",
    "status": "Pending"
  },
  {
    "company": {
      "name": "Company 3",
      "symbol": "three"
    },
    "description": "test",
    "status": "Pending"
  }
]
const filters = ["Company 1", "Company 3"];
const result = fn(data, filters);
console.log(result);

于 2021-07-07T03:12:26.330 回答
1

这只是一个简单的...

const _ = require('lodash');
. . .
const data = [
  {
    company: { name: "Company 1", symbol: "one",   }, description: "test", status: "Pending", },
  { company: { name: "Company 2", symbol: "two",   }, description: "test", status: "Pending", },
  { company: { name: "Company 3", symbol: "three", }, description: "test", status: "Pending", },
];

const desired = new Set([
  "Company 1",
  "Company 3"
]);

const filtered = data.filter( o => desired.has( o.company.name ) )
于 2021-07-07T03:25:26.330 回答