-1

I have the following data array that I wanna filter by company name/names. filter company name could be one or many.

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"]

Expected Result

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

Attempted the following

  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);
  }

I tried following the solution here, since my data array is nested it doesn't seem to work. any help will be appreciated!

yellowSub
  • 209
  • 3
  • 12

4 Answers4

2

You can filter the result if company.name exists in the filter array

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);
DecPK
  • 24,537
  • 6
  • 26
  • 42
1

Since you have filter as an array and data as an array as well, if your filter goes large, then O(n2) complexity may hurt. A faster solution will be to convert filter array in a map, to have constant time access like-

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)
Pawan Sharma
  • 1,842
  • 1
  • 14
  • 18
1

Problems in your approach:

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])
    )
  );
};

An alternative

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);
Ramesh Reddy
  • 10,159
  • 3
  • 17
  • 32
1

It's just a simple...

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 ) )
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135