Prozak
Prozak

Reputation: 303

Filtering an array by category name

I would like to filter an array of images based on their category property.

I am able to map and push the category property of all images into a new array and set the state to the new array.

However, I am stuck figuring out how to check for duplicates in the new array, and NOT push a new value if it's already exists.

interface Asset {
  id: string
  name: string
  category: string
} 
import * as React from "react"

interface MediaLibraryProps {
  mediaLibrary: Asset[]
}

class MediaLibrary extends React.Component<MediaLibraryProps> {
  state = {
    categories: [],
  }

categoryFilter = () => {
    const categoryArray: any = []
    this.props.mediaLibrary.filter(file => {
      if (file.category !== categoryArray) {
        categoryArray.push(file.category)
      } else {
        return
      }
    })
    this.setState({
      categories: categoryArray
    })
    console.log(this.state.categories)
  }
render() {
    const select = this.state.categories.map(category =>
      <option key={category}>{category}</option>
    )
return (
      <div>
        <select>
          { select }
        </select>
        <button onClick={this.categoryFilter}>LOG</button>
      </div>
    )
  }
}

export default MediaLibrary

I'm expecting only unique names to be pushed to the categories array.

Actual results - everything is being pushed.

Upvotes: 0

Views: 566

Answers (2)

Michael Kantz
Michael Kantz

Reputation: 187

See Remove duplicate values from JS array

Example:

uniqueArray = a.filter(function(item, pos) {
    return a.indexOf(item) == pos;
})

Quick answer for your question:

    const categoryArray: any = []
    this.props.mediaLibrary.filter(file => {
      if (categoryArray.indexOf(file.category) < 0) {
        categoryArray.push(file.category)
      } else {
        return
      }
    })
    this.setState({
      categories: categoryArray
    })
    console.log(this.state.categories)

Better approach:

The filter here is unnecessary. better approach is to use map.

    const categoryArray: any = []
    this.props.mediaLibrary.map(file => {
      if (categoryArray.indexOf(file.category) < 0) {
        categoryArray.push(file.category)
      }
    })
    this.setState({
      categories: categoryArray
    })
    console.log(this.state.categories)

Upvotes: 1

Engineer
Engineer

Reputation: 1261

It can be achieved with filter.As per question,

let filteredData = this.props.mediaLibrary.filter(file => file.category !== categoryArray);

Upvotes: 0

Related Questions