Reputation: 8297
let data = [
{
title: 'aa',
releases: [
{ version: '1', owner: 'john'},
{ version: '2', owner: 'bob'}
]
},
{
title: 'bb',
releases: [
{ version: '1', owner: 'john'},
{ version: '2', owner: 'jack'}
]
},
{
title: 'cc',
releases: [
{ version: '1', owner: 'doo'},
{ version: '2', owner: 'park'}
]
},
]
I have an array of objects that looks like above.
I am trying to filter the objects by the owner
inside the releases
array.
What I've tried is
data.filter(item =>
['john'].some(
item.releases.some(
obj=>obj.owner.toLowerCase().includes(['john'])
)
)
)
I used an array of string(s) to have multiple search queries in the future. But this gives me an error
Uncaught TypeError: true is not a function
How can I solve this?
The result should be all objects that have john
as an owner in any of its releases
array
Upvotes: 1
Views: 171
Reputation: 21130
If the intent is to check for a single name you can negate this answer. However if the intent of the question is to check for multiple names you can fix your code in the following way.
The issue is that you're providing a true
/false
value to the first some
call, this should be a function.
const names = ['john'];
data.filter(item =>
names.some(name => // added `name =>`
item.releases.some(release =>
release.owner.toLowerCase().includes(name) // changed `['john']` into `name`
)
)
);
However, you can also achieve the same functionality with less iterations by using an regex.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping
const escapeRegExp = string => string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const names = ['john'],
pattern = names.map(escapeRegExp).join("|"),
regex = new RegExp(pattern, "i"); // i = ignore case (removing the need of toLowerCase)
data.filter(item => item.releases.some(release => release.owner.match(regex)));
Upvotes: 0
Reputation: 307
You can try this:
let data = [
{
title: 'aa',
releases: [
{ version: '1', owner: 'john'},
{ version: '2', owner: 'bob'}
]
},
{
title: 'bb',
releases: [
{ version: '1', owner: 'john'},
{ version: '2', owner: 'jack'}
]
},
{
title: 'cc',
releases: [
{ version: '1', owner: 'doo'},
{ version: '2', owner: 'park'}
]
},
];
var result = data.filter(x => x.releases.some(rls => rls.owner.toLowerCase().includes(['john'])));
console.log(result);
Upvotes: 0
Reputation: 187034
That ['john'].some(
call isn't really helping. You have the logic already without that.
You are getting that error because you are passing the result of some()
(which returns a boolean) to some()
(which expect a function).
Also, when asking if a string includes a string, you should pass in a string, not an array.
const filteredData = data.filter(item =>
item.releases.some(
obj => obj.owner.toLowerCase().includes('john')
)
)
Upvotes: 2
Reputation: 37755
some expects a function not value, in the outer most some you're just passing the value you need to pass function instead
data.filter(item =>
['john'].some( () => // <--- function
item.releases.some(
obj=>obj.owner.toLowerCase().includes('john')
)
)
)
Infact you don't need outer some
data.filter(item =>
item.releases.some(
obj=>obj.owner.toLowerCase().includes('john')
)
)
Upvotes: 0