-1

I am trying to learn multi filter with React Table. Here is my Demo/Fiddle

I am trying to eliminate duplicate values in dropdown of my React Table

        <Select
          style={{ width: "50%", marginBottom: "20px" }}
          onChange={entry => {
            this.setState({ select2: entry });
            this.onFilteredChangeCustom(
              entry.map(o => {
                return o.value;
              }),
              "firstName"
            );
          }}
          value={this.state.select2}
          multi={true}
          options={this.state.data.map((o, i) => {
            return { id: i, value: o.firstName, label: o.firstName };
          })}
        />

I am getting duplicate values in dropdown. Kindly help me how to eliminate the duplicate values in dropdown.

Duplicate values in Dropdown. As you can see Sam is coming twice.

Screenshot 2. Jones1 is also coming twice.

Basically I am filtering each column and the above function basically deals with the filtering functionality. Kindly see the screenshot. There is the issue - there are some values which are multiple times in my Json array. But in the dropdown they should come only once.

Edit 1 - I want to a generalized solution which can be applied to any number of dropdowns. Till now I have got two good answers. But both answers are not generalized. I want to extend this unique feature to all columns. I will have 15 to 20 columns. That is why I need a generalized solution.

tommy123
  • 587
  • 1
  • 10
  • 28
  • You're asking how to remove duplicates from a collection in JavaScript? – Dave Newton Jan 02 '19 at 18:42
  • @Dave Newton Basically I am not aware of Collection. I am filtering each column and the above function basically deals with the filtering functionality. Kindly see the screenshot. There is the issue - there are some values which are multiple times in my Json array. But in the dropdown they should come only once. – tommy123 Jan 02 '19 at 18:45
  • Collection (noun): a group of things or people. My point is that you're basically asking how to filter a collection, which is covered all over the place. – Dave Newton Jan 02 '19 at 21:05

2 Answers2

1
var names = this.state.data.map((o, i) => {
  return o.firstName
})

var uniqueNames = names.filter(function(i, index){
    return names.indexOf(i) >= index
});

https://codesandbox.io/s/40n0jnzk5x See fix for firstdropdown

Helper function

var uniqueOptions = (objectsArray, objectKey) => {

   var a = objectsArray.map((o, i) => {
     return o[objectKey]
   })

   return a.filter(function(i, index){
      return a.indexOf(i) >= index
   })
}

Usage for first name dropdown (Same for any other dropDown)

      ....
      multi={true}
      options={this.uniqueOptions(this.state.data, 'firstName').map((name, i) => {
        return { id: i, value: name, label: name };
      })}
      ...

Ideally, you would calculate this outside render to prevent recalculation on every render but you get the idea

varoons
  • 3,807
  • 1
  • 16
  • 20
  • Yes I understand your logic. But how can I use this in my Code. Can you please fork my fiddle and show me. There are two dropdowns. Please update my Sandbox and show how it works in my code. This is my fiddle - https://codesandbox.io/s/w2wjnz61l5 – tommy123 Jan 02 '19 at 18:51
  • I want a generalized solution that will work for all fields like firstname, lastname. Your solution is only for firstname. – tommy123 Jan 02 '19 at 18:55
  • Apply the same for last name. You could write a function to address both at the same time but i think this is a more concise solution – varoons Jan 02 '19 at 18:56
  • Can we have a more generalized solution. See I have to basically 2 lines of code for every dropdown. If I have 15 columns have to write this again and again - var names = this.state.data.map((o, i) => { return o.firstName }) – tommy123 Jan 02 '19 at 18:59
  • Added a helper function you can use directly why setting your options – varoons Jan 02 '19 at 19:05
  • Can you please fork the fiddle and show me? Basically I want to have this for all columns. Kindly update the Fiddle/Sandbox and show how it works in my code. This is the fiddle - https://codesandbox.io/s/40n0jnzk5x – tommy123 Jan 02 '19 at 19:08
  • I have provided the full solution. The forum is for providing direction not completing code. Just add the uniqueOptions function to you class/component and use it on every drop down – varoons Jan 02 '19 at 19:09
  • Good Solution. Understood. Thanks a lot – tommy123 Jan 02 '19 at 19:19
1

Try this

const getOptions = propertyName => {
  return this.state.data.reduce((accum, elem, i) => {
    const accumulator = [...accum];
    if (!accumulator.some(e => e.value === elem[propertyName])) {
      accumulator.push({
        id: i,
        value: elem[propertyName],
        label: elem[propertyName]
      });
    }
    return accumulator;
  }, []);
};

getOptions("FirstName")

  • I want a generalized solution that will work for all fields like firstname, lastname. Your solution is only for firstname. – tommy123 Jan 02 '19 at 18:53
  • Can you please fork the fiddle and show me? Basically I want to have this for all columns. Kindly update the Fiddle/Sandbox and show how it works in my code. This is the fiddle -https://codesandbox.io/s/yvpq6lx4j1 – tommy123 Jan 02 '19 at 19:10