Reputation: 1164
Say I have an array of objects that follows the pattern below:
var posts = [
{
title: post_ab,
category_array : [
{ id: 1, slug: category-a },
{ id: 2, slug: category-b }
]
},
{
title: post_ac,
category_array : [
{ id: 1, slug: category-a },
{ id: 3, slug: category-c }
]
},
{
title: post_bc,
category_array : [
{ id: 2, slug: category-b },
{ id: 3, slug: category-c }
]
}
]
I'm trying to filter the above array, and only return values where the category_array contains a slug matching a specified value.
For example, if I wanted to filter against 'category-c', only the 2nd and 3rd values (post_ac and post_bc) would be returned.
I've tried with nested filters, which is getting me nowhere:
var currentCategory = 'category-b';
var filteredPosts = function( posts ) {
return posts.filter( function( post ){
return post.category_array.filter( function( category ){
return category.slug === currentCategory;
})
})
}
Upvotes: 3
Views: 1400
Reputation: 19070
You can make a Array.prototype.find() to get first element with slug
equal to 'category-b'
in the array category_array
and returning that element if exists will be evaluated as truthy, or falsey if not exist, by the Array.prototype.filter():
var posts = [{title: 'post_ab',category_array : [{ id: 1, slug: 'category-a' },{ id: 2, slug: 'category-b' }]},{title: 'post_ac',category_array : [{ id: 1, slug: 'category-a' },{ id: 3, slug: 'category-c' }]},{title: 'post_bc',category_array : [{ id: 2, slug: 'category-b' },{ id: 3, slug: 'category-c' }]}],
currentCategory = 'category-b',
result = posts.filter(function (p) {
// Return only the very first element found
return p.category_array.find(function (c) {
return currentCategory === c.slug;
});
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0
Reputation: 2776
Let's combine some with filter
var posts = [
{
title: 'post_ab',
category_array : [
{ id: 1, slug: 'category-a' },
{ id: 2, slug: 'category-b' }
]
},
{
title: 'post_ac',
category_array : [
{ id: 1, slug: 'category-a' },
{ id: 3, slug: 'category-c' }
]
},
{
title: 'post_bc',
category_array : [
{ id: 2, slug: 'category-b' },
{ id: 3, slug: 'category-c' }
]
}
];
var result = posts.filter(a => a.category_array.some(cat => cat.slug.includes('a')));
console.log(result);
Upvotes: 2
Reputation: 32145
You have to use Array.prototype.some() in the inner loop:
var filteredPosts = function(posts) {
return posts.filter(function(post){
return post["category_array"].some(function(category){
return category.slug === currentCategory;
});
});
}
It will return a boolean
result that can be used in the .filter()
callback.
Upvotes: 6
Reputation: 331
You can use Array.prototype.some
posts.filter(
(elem) => (
elem.category_array.some(
elem => elem.slug === currentCategory;
)
)
)
Upvotes: 0