0

trying to make a dynamic filter, it reads the array and returns a button that then filters the data rendered. I'm trying to get it to only show unique filters though and cant figure out how. My current code:

 const typeFilter = data?.venuesByCountry.map(v => (
    v.venueTypes.map(a =>(
    <>
      <Button onClick={() => filterC(`${a}`)}>{a}</Button>
    </>
    ))
  ))

returns:

["VENUE"]
["RESTAURANT"]
["BAR", "DRINKS", "PUB"]
["BAR", "DRINKS"]
["BAR", "DRINKS"]

But I want it to return something like:

["VENUE"]
["RESTAURANT"]
["BAR"]
["DRINKS"]
["PUB"]

or:

["VENUE"]
["RESTAURANT"]
["BAR", "DRINKS", "PUB"]

any help would be much appreciated!

edit

Here's the solution I went with:

  const typeFilter = data?.venuesByCountry.reduce((acc, item) => {
    item.venueTypes.forEach(v => {
      (acc.indexOf(v) < 0) ? acc.push(v) : null })
      return acc
    }, []).map(a => (
      <>
      <Button $style={{marginRight:'6px'}} onClick={() => filterC(`${a}`)}>{a.toString().replace(/_/g, ' ')}</Button>
      </>
  ))

Appreciate the fast reply's

2 Answers 2

1

you want to flatten your array,

  const newArray = data.venuesByCountry.reduce((acc, item) => {
    return acc.concat(item.venueTypes);
  }, [])

if your data is like the following,

const venuesByCountry = [
    { venueTypes: [1, 2] },
    { venueTypes: [3, 4] },
]

then you'll get newArray to be [1,2,3,4]

If you want to make item unique, then you could do

const venuesByCountry = [
    { venueTypes: [1, 2, 3] },
    { venueTypes: [3, 4] },
]
const newArray = venuesByCountry.reduce((acc, item) => {
    item.venueTypes.forEach(v => {
        if (acc.indexOf(v) < 0) {
            acc.push(v)
        }
    })
    return acc
}, [])

Of course, there're lots of Lodash function you can use to replace the above.

Sign up to request clarification or add additional context in comments.

2 Comments

This got the array to: ["VENUE", "RESTAURANT", "BAR", "DRINKS", "PUB", "BAR", "DRINKS", "BAR", "DRINKS"] thanks any now I need to get it to ["VENUE", "RESTAURANT", "BAR", "DRINKS", "PUB"] so it only shows unique entries
you can add a lodash uniq, the flatten also supported by lodash. But i can code a simple version, will update the answer.
1

first: you need to merge your data array using the flat method that will create a new array with all sub-array elements concatenated into it recursively up to the specified depth

ex: :

const data =  [
  ["VENUE"],
  ["RESTAURANT"],
  ["BAR", "DRINKS", "PUB"],
  ["BAR", "DRINKS"],
  ["BAR", "DRINKS"]
];

const mergedData = data.flat();

console.log(mergedData)

// will return ["VENUE", "RESTAURANT", "BAR", "DRINKS", "PUB", "BAR", "DRINKS", "BAR", "DRINKS"]

second : you need to remove duplicates from an array

The simplest approach (in my opinion) is to use the Set object which lets you store unique values of any type. In other words, Set will automatically remove duplicates for us.

Supplement to the ex :


const uniqueData = [...new Set(mergedData)]
console.log(uniqueData)

Implementation in your code :

 const typeFilter = data && [...new Set(data.venuesByCountry.flat())].map(v => (
    v.venueTypes.map(a =>(
    <>
      <Button onClick={() => filterC(`${a}`)} id={a}>{a}</Button>
    </>
    ))
  ))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.