user3348410
user3348410

Reputation: 2833

es6 filter and find same items of object

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?

Upvotes: 1

Views: 289

Answers (4)

Jiml
Jiml

Reputation: 397

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

Upvotes: 0

Hung Nguyen
Hung Nguyen

Reputation: 1156

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
}, [])

Upvotes: 0

Dhananjai Pai
Dhananjai Pai

Reputation: 6005

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

Upvotes: 2

Yannick K
Yannick K

Reputation: 5422

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

Upvotes: 0

Related Questions