Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional Javascript Filter

I have a object containing the following:

assets = [
  { id: 1, type: 'image', url: 'image.jpg' },
  { id: 2, type: 'video', url: 'video.mp4' },
]

I'd like to filter based on user selection of IMAGE, VIDEO, or ALL.

I cannot think of a clean way to filter use for the ALL case.

currentOption = 'image'
assets.filter(asset => asset.type === currentOption)

This will work for IMAGE or VIDEO, but not ALL.

I could check in my filter function:

const currentOption = 'all'
const filterFunc = asset => {
  if (currentOption == 'all') return true
  return asset.type === currentOption
}
assets.filter(filterFunc)

But wouldn't it be better to short-circuit the filter to not iterate each item?

Edit: To answer questions why not skip filter all together. I was trying to keep it framework agnostic. But this is rendered using react. So I would have to do something like:

<div>
{currentOption === 'all' ?
  assets.map(asset => 
   <img src={asset.url} />
  )
  :
  assets.filter(asset => asset.type === currentOption).map(asset =>
   <img src={asset.url} />
  )
}
</div>

Plus this doesn't even account for the code to display a video. Basically I was trying to reduce duplication in the view code.

like image 583
dardub Avatar asked Jun 27 '17 20:06

dardub


2 Answers

You could use the ternary operator to decide whether or not to apply the filter:

currentOption === 'all' ? assets : assets.filter(asset => asset.type === currentOption)

The mapping to images, that you added to the end of your question, could be written like this:

(currentOption === 'all' ? assets : assets.filter(asset => asset.type === currentOption))
    .map( asset => <img src={asset.url} /> )
like image 185
trincot Avatar answered Sep 25 '22 01:09

trincot


I would go with what you suggested, more or less:

assets.filter(asset => currentOption === "all" || asset.type === currentOption);

Keep in mind that filter() iterates over all of the items anyway.

like image 32
alonkol Avatar answered Sep 25 '22 01:09

alonkol