0

I have a list of JS objects in my application

list=[ {id: 152956, appname: 'tst', approvalStatus: "Validated",children: [] ,clapp: {owner: '07D', code: 'TST',fullCLAPP: '07D/TST/G-PM'},company: {id: 9705, name: 'Dot Com', code: '07D'},connectionType: "",dnsNode: "",kind: "Standard",validatedOnce: true} , 
{id: 19876, appname: 'comptest', approvalStatus: "Validated",children: [] ,clapp: {owner: '07D', code: 'CMP',fullCLAPP: '07D/CMP/G-PM'},
company: {id: 765, name: 'IT jira', code: '07D'},connectionType: "",dnsNode: "",kind: "Standard",validatedOnce: true}]

I have to filter according to the object

ob = {appname: 'airline', code: '07',company: {name:'abcd'}}

how do I do it?

I have tried with

list.filter(data => Object.entries(ob).every(([k, v]) => typeof v === 'string'? data[k].toLowerCase().includes(v.toLowerCase()): typeof v ==='object'? Object.entries(v).every(([key ,value]) => data[k][key].toLowerCase().includes(value.toLowerCase())): data[k] === v));

I tried the above with the if...else block also, it's not working

Sebastian Kaczmarek
  • 8,120
  • 4
  • 20
  • 38
  • 1
    I notice that you've taken your [previous question](https://stackoverflow.com/questions/75480896/search-for-all-the-objects-in-a-list-using-all-its-properties) (as well as my answer to that question) and added a level of object nesting to both your data and your filter object. I also notice that your data now contains arrays. What's the expected behavior when filtering on array values? – Robby Cornelissen Feb 22 '23 at 06:26
  • What is your desired result? what is not working? Please include all relevant information in your question – Carsten Løvbo Andersen Feb 22 '23 at 06:27
  • Is the filter criteria fixed? Do we always use same fields - `appname`, `code`, and `company`? – Nikhil Feb 22 '23 at 06:27
  • on filtering array values i have to get the list of objects that contains the company with given name – tasmia firdose Feb 22 '23 at 06:52
  • 1
    I was referring to the `children` array in your data. What if the filter object contains values for that `children` property? Do all elements need to be present in the data? In the same order as the filter object? Do all fields need to match? The same questions apply to objects: if you filter for a `company: { name: 'abcd', code: '001' }`, do both properties need to match? Only one? Are we looking for string equality or substring matches? In short: your question is broad to the point that it can't be answered in its current state. – Robby Cornelissen Feb 22 '23 at 07:40

1 Answers1

0

Here is a recursive solution that filters and returns all elements from a given list of elements that contain matching data in a given subset object.

export const containsSubset = (superset: any, subset: any): boolean => {
  return Object.keys(subset).reduce((subsetInSuperset: boolean, key: string) => {

    // In case the property is an object, check inside that object
    if (isObject(subset[key])) {
      return subsetInSuperset && containsSubset(superset[key], subset[key]);
    }

    // In case the property is an array, check for every element
    if (Array.isArray(subset[key])) {
      return subsetInSuperset &&
        subset[key].reduce((subsetArrayInSupersetArray: boolean, arrayElement: any, i: number) =>
            subsetArrayInSupersetArray && containsSubset(superset[key][i], arrayElement),
          true,
      );
    }

    // In case the property is a primitive, we can simply compare directly
    return subsetInSuperset && superset[key] === subset[key];
  }, true); // The initialization value must be true (since we use &&)
};

I nicked this function from another Stackoverflow question (Check if a value is an object in JavaScript):

export const isObject = (variable: any) =>
  typeof variable === 'object' && !Array.isArray(variable) && variable !== null;

With your test data (modified)

const list = [
  {
    id: 152956,
    appname: 'tst',
    approvalStatus: 'Validated',
    children: [],
    clapp: { owner: '07D', code: 'TST', fullCLAPP: '07D/TST/G-PM' },
    company: { id: 9705, name: 'Dot Com', code: '07D' },
    connectionType: '',
    dnsNode: '',
    kind: 'Standard',
    validatedOnce: true,
  },
  {
    id: 19876,
    appname: 'comptest',
    approvalStatus: 'Validated',
    children: [],
    clapp: { owner: '07D', code: 'CMP', fullCLAPP: '07D/CMP/G-PM' },
    company: { id: 765, name: 'IT jira', code: '07D' },
    connectionType: '',
    dnsNode: '',
    kind: 'Standard',
    validatedOnce: true,
    testArray: ['a', 'q', { id: 3, name: 'a' }],
  },
];

const testFalse = {
  appname: 'airline',
  code: '07',
  company: { name: 'abcd' },
};

const testTrue = {
  appname: 'comptest',
  clapp: { code: 'CMP' },
  company: { name: 'IT jira', code: '07D' },
  testArray: ['a', 'q', { id: 3, name: 'a' }],
};

Run code

// Empty array
const elementsWithSubsetEmpty = list.filter((x) => containsSubset(x, testFalse));

// Array with filtered elements of your "list" variable that contain the properties of "testTrue"
const elementsWithSubset = list.filter((x) => containsSubset(x, testTrue)); 
CoderApprentice
  • 425
  • 1
  • 6
  • 21