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.
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} /> )
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With