1

I have a question about filtering with ES6:

I have some data which I need to filter with other objects

My data is:

let data = [
    {
        id: 1,
        names: ['A', 'B']
    },
    {
        id: 2,
        names: ['C']
    }
]

I have another object as:

let nameValues = [
    {
        name: 'A',
        selected: false
    },
    {
        name: 'B',
        selected: true
    },
    {
        name: 'C',
        selected: false
    },
    {
        name: 'D',
        selected: true
    }
]

I'm first getting selected == true items in selectedNames with:

let selectedNames = nameValues.filter(function(item) {
    return item.selected
})

and I'm getting result:

selectedNames = [
    {
        name: 'A',
        selected: true
    },
    {
        name: 'D',
        selected: true
    }
]

and I need to compare it with data, getting items in data where item.names have selectedNames in it.

I don't need exactly matching -- I need the items in data object which have in their names array my selectedNames object name values:

In this case I need to get like this result of my data object:

Here is item not matching 100% with my selectedNames but it have one of these values which I am looking for

let data = [
    {
        id: 1,
        names: ['A', 'B']
    },
]

How to do that with es6?

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
user3348410
  • 2,733
  • 10
  • 51
  • 85
  • 2
    Possible duplicate of [How do I check if an array includes an object in JavaScript?](https://stackoverflow.com/questions/237104/how-do-i-check-if-an-array-includes-an-object-in-javascript) – Dan O Oct 10 '19 at 14:54

4 Answers4

2

Your approach was right. I just stored the selectedNames as an array for easier lookup.

In the data.filter, you can check if the some name is available in the selectedNames array

let data = [
    {
        id: 1,
        names: ['A', 'B']
    },
    {
        id: 2,
        names: ['C']
    }
]

let nameValues = [
    {
        name: 'A',
        selected: false
    },
    {
        name: 'B',
        selected: true
    },
    {
        name: 'C',
        selected: false
    },
    {
        name: 'D',
        selected: true
    }
]

let selectedNames = nameValues.filter(item => item.selected).map(x => x.name);

let result = data.filter(obj => obj.names.some(name => selectedNames.includes(name)));

console.log(result);
Dhananjai Pai
  • 5,914
  • 1
  • 10
  • 25
0

You could use a nested for loop over both arrays and check whether each individual selected name is in any of the data elements:

const data = [
    { id: 1, names: ['A', 'B'] },
    { id: 2, names: ['C'] },
]

const selectedNames = [
    { name: 'A', selected: true },
    { name: 'D', selected: true },
    { name: 'B', selected: true },
]

const result = [];
for (const element of data) {
  for (const name of selectedNames) {
    if (element.names.includes(name.name) && !result.includes(element)) {
      result.push(element);
    }
  }
}

console.log( result );
Yannick K
  • 4,887
  • 3
  • 11
  • 21
0

Just two loop, example using reduce:

let data = [
    {
        id: 1,
        names: ['A', 'B']
    },
    {
        id: 2,
        names: ['C']
    }
]

let selectedNames = [
    {
        name: 'A',
        selected: true
    },
    {
        name: 'D',
        selected: true
    }
]

selectedNames.reduce((result, selectedName) => {
    data.forEach(item => {
        if (item.names.includes(selectedName.name)) {
            result.push(item)
        }
    })
    return result
}, [])
Hung Nguyen
  • 1,026
  • 11
  • 18
0

Obviously Names will repeat in Data object

const nameValues = [
  {
    name: "A",
    selected: false
  },
  {
    name: "B",
    selected: true
  },
  {
    name: "C",
    selected: true
  },
  {
    name: "D",
    selected: false
  }
];

let data = [
  {
    id: 1,
    names: ["A", "B"]
  },
  {
    id: 2,
    names: ["C"]
  },
  {
    id: 3,
    names: ["C", "D"]
  }
];

let selectedNames = nameValues
  .filter(item => item.selected)
  .reduce((acc, item) => {
    const selected = data.filter(dataItem => {
      return (
        dataItem.names.includes(item.name) &&
        !acc.some(i => i.id === dataItem.id)
      );
    });
    return [...acc, ...selected];
  }, []);

console.log(selectedNames);
Jiml
  • 377
  • 3
  • 9