Reputation: 542
I have below an array called data
:
const data = [
{id:1 ,name: 'Product A', image: 'pic-001.jpg', tags: [{id:50 ,productname: 'Test A'}]},
{id:2 ,name: 'Product B', image: 'pic-002.jpg', tags: [{id:60,productname: 'Test A'}]},
{id:3 ,name: 'Product C', image: 'pic-003.jpg', tags: [{id:70,productname: 'Test B'}]}
]
//I have an array of objects. Inside these objects, there is another array: tags.
//My question is, how would I filter the multiple fields inside the data array
//if I filtered by, e.g., a id:1, I'd receive the following returned:
var output1 = [{id:1 ,name: 'Product A', image: 'pic-001.jpg', tags: [{id:50 ,productname: 'Test A'}]}]
// if I filtered by, e.g., a productname: 'Test A', I'd receive the following returned:
var output2 = [ {id:1 ,name: 'Product A', image: 'pic-001.jpg', tags: [{id:50 ,productname: 'Test A'}]}, {id:2 ,name: 'Product B', image: 'pic-002.jpg', tags: [{id:60,productname: 'Test A'}]}]
//I have tried the below code but it's not working
const filter = '1';
//const filter = 'Test A';
const Result = data.filter((item) => {
return (
item.id.toString().indexOf(filter) > -1 ||item.tags.indexOf(filter) > -1
);
});
console.log(Result)
Upvotes: 0
Views: 79
Reputation: 6039
Since the tags
is an array of objects inside each product
object, we can make use of Array.some
and find if any of the tag's productname
is
matching with the required value that we are looking for
const data = [
{id:1 ,name: 'Product A', image: 'pic-001.jpg', tags: [{id:50 ,productname: 'Test A'}]},
{id:2 ,name: 'Product B', image: 'pic-002.jpg', tags: [{id:60,productname: 'Test A'}]},
{id:3 ,name: 'Product C', image: 'pic-003.jpg', tags: [{id:70,productname: 'Test B'}]}
];
const getFilteredData = (data, value) => data.filter(datum =>
datum.id.toString().includes(value.toString()) || datum.tags.some(tag => tag.productname.includes(value))
);
console.log(getFilteredData(data, 1));
console.log(getFilteredData(data, 'Test A'));
console.log(getFilteredData(data, 'Test B'));
.as-console-wrapper {
max-height: 100% !important;
}
Upvotes: 1
Reputation: 6418
You can create respective functions for filtering the array. Say I've created two functions filterByTag(key, value)
and filterBy(key, value)
.
In the filterByTag
function, provide two arguments key
& value
. Where the key
is the object key inside the tags
array.
This is similar to the filterBy
function. The fitlerBy
is applied directly to the data
array.
const data = [
{id:1, name: 'Product A', image: 'pic-001.jpg', tags: [{id:50, productname: 'Test A'}]},
{id:2, name: 'Product B', image: 'pic-002.jpg', tags: [{id:60, productname: 'Test A'}]},
{id:3, name: 'Product C', image: 'pic-003.jpg', tags: [{id:70, productname: 'Test B'}]}
];
const filterByTag = (key, value) => data.filter(item => item.tags.find(x => x[key] === value));
const filterBy = (key, value) => data.filter(item => item[key] === value);
console.log(filterByTag('productname', 'Test A'));
console.log(filterByTag('id', 60));
console.log(filterBy('id', 1));
console.log(filterBy('name', 'Product A'));
.as-console-wrapper{min-height: 100%!important; top: 0}
Upvotes: 1
Reputation: 50954
Using .indexOf()
on an array of objects to check for a string value (eg: 'Test A'
) won't work, as your string doesn't equal an object within your array. Instead, you can use .some()
to specify the search logic using its callback and return true
once you find a product_name
that equals your filter
:
const data = [{ id: 1, name: 'Product A', image: 'pic-001.jpg', tags: [{ id: 50, productname: 'Test A' }] }, { id: 2, name: 'Product B', image: 'pic-002.jpg', tags: [{ id: 60, productname: 'Test A' }] }, { id: 3, name: 'Product C', image: 'pic-003.jpg', tags: [{ id: 70, productname: 'Test B' }] } ];
//const filter = '1';
const filter = 'Test A';
const Result = data.filter((item) =>
item.id.toString().includes(filter) || item.tags.some(item => item.productname === filter)
);
console.log(Result)
I've also updated your .indexOf()
call on your first string/id to use .includes()
, which is a more modern way to check whether your string contains a value.
Upvotes: 1