Dynamic array filtering by object property
I have a react live search dropdown component that filters through an array of objects by a search term. It filters my objects by title and then returns a list of all the related objects. This works fine.
Current:
Data Structure
data: [
{ id: 1, title: 'Some title here' },
{ id: 2, title: 'Another title' },
{ id: 3, title: 'last title' },
]
Component
<LiveSearch
term={term}
data={data} />
Inside Live search component
Filter data by term and render list
return data
.filter(item => item.title.toLowerCase().includes(term.toLowerCase())
.map((item, idx) => <li key={idx}>{item.title}</li>
My objects to search by are getting more advanced and what I would like to be able to do is pass into my component an array of property names I would like to compare to the search term.
My thinking process behind it is to loop through the object properties and if on of the properties matches the term the loop breaks and returns true adding that object to the list of items to be displayed.
Goal
Data Structure
data: [
{ id: 1, country: 'Canada', title: 'Some title here' },
{ id: 2, country: 'Australia', title: 'Another title' },
{ id: 3, country: 'Netherlands', title: 'last title' },
]
Component
<LiveSearch
searchFields={['country', 'title']}
term={term}
data={data} />
Inside Component filtering
return data
.filter(item => {
// Dynamic filtering of terms here
})
.map((item, idx) => <li key={idx}>{item.title}</li>
Inside the filter I'm trying to get a loop through the array and dynamically produce logic similar to this
item.searchFields[0].toLowerCase().includes(term.toLowerCase()) ||
item.searchFields[1].toLowerCase().includes(term.toLowerCase())
But obviously could loop over an infinite number of searchfields/properties
javascript arrays filter
add a comment |
I have a react live search dropdown component that filters through an array of objects by a search term. It filters my objects by title and then returns a list of all the related objects. This works fine.
Current:
Data Structure
data: [
{ id: 1, title: 'Some title here' },
{ id: 2, title: 'Another title' },
{ id: 3, title: 'last title' },
]
Component
<LiveSearch
term={term}
data={data} />
Inside Live search component
Filter data by term and render list
return data
.filter(item => item.title.toLowerCase().includes(term.toLowerCase())
.map((item, idx) => <li key={idx}>{item.title}</li>
My objects to search by are getting more advanced and what I would like to be able to do is pass into my component an array of property names I would like to compare to the search term.
My thinking process behind it is to loop through the object properties and if on of the properties matches the term the loop breaks and returns true adding that object to the list of items to be displayed.
Goal
Data Structure
data: [
{ id: 1, country: 'Canada', title: 'Some title here' },
{ id: 2, country: 'Australia', title: 'Another title' },
{ id: 3, country: 'Netherlands', title: 'last title' },
]
Component
<LiveSearch
searchFields={['country', 'title']}
term={term}
data={data} />
Inside Component filtering
return data
.filter(item => {
// Dynamic filtering of terms here
})
.map((item, idx) => <li key={idx}>{item.title}</li>
Inside the filter I'm trying to get a loop through the array and dynamically produce logic similar to this
item.searchFields[0].toLowerCase().includes(term.toLowerCase()) ||
item.searchFields[1].toLowerCase().includes(term.toLowerCase())
But obviously could loop over an infinite number of searchfields/properties
javascript arrays filter
add a comment |
I have a react live search dropdown component that filters through an array of objects by a search term. It filters my objects by title and then returns a list of all the related objects. This works fine.
Current:
Data Structure
data: [
{ id: 1, title: 'Some title here' },
{ id: 2, title: 'Another title' },
{ id: 3, title: 'last title' },
]
Component
<LiveSearch
term={term}
data={data} />
Inside Live search component
Filter data by term and render list
return data
.filter(item => item.title.toLowerCase().includes(term.toLowerCase())
.map((item, idx) => <li key={idx}>{item.title}</li>
My objects to search by are getting more advanced and what I would like to be able to do is pass into my component an array of property names I would like to compare to the search term.
My thinking process behind it is to loop through the object properties and if on of the properties matches the term the loop breaks and returns true adding that object to the list of items to be displayed.
Goal
Data Structure
data: [
{ id: 1, country: 'Canada', title: 'Some title here' },
{ id: 2, country: 'Australia', title: 'Another title' },
{ id: 3, country: 'Netherlands', title: 'last title' },
]
Component
<LiveSearch
searchFields={['country', 'title']}
term={term}
data={data} />
Inside Component filtering
return data
.filter(item => {
// Dynamic filtering of terms here
})
.map((item, idx) => <li key={idx}>{item.title}</li>
Inside the filter I'm trying to get a loop through the array and dynamically produce logic similar to this
item.searchFields[0].toLowerCase().includes(term.toLowerCase()) ||
item.searchFields[1].toLowerCase().includes(term.toLowerCase())
But obviously could loop over an infinite number of searchfields/properties
javascript arrays filter
I have a react live search dropdown component that filters through an array of objects by a search term. It filters my objects by title and then returns a list of all the related objects. This works fine.
Current:
Data Structure
data: [
{ id: 1, title: 'Some title here' },
{ id: 2, title: 'Another title' },
{ id: 3, title: 'last title' },
]
Component
<LiveSearch
term={term}
data={data} />
Inside Live search component
Filter data by term and render list
return data
.filter(item => item.title.toLowerCase().includes(term.toLowerCase())
.map((item, idx) => <li key={idx}>{item.title}</li>
My objects to search by are getting more advanced and what I would like to be able to do is pass into my component an array of property names I would like to compare to the search term.
My thinking process behind it is to loop through the object properties and if on of the properties matches the term the loop breaks and returns true adding that object to the list of items to be displayed.
Goal
Data Structure
data: [
{ id: 1, country: 'Canada', title: 'Some title here' },
{ id: 2, country: 'Australia', title: 'Another title' },
{ id: 3, country: 'Netherlands', title: 'last title' },
]
Component
<LiveSearch
searchFields={['country', 'title']}
term={term}
data={data} />
Inside Component filtering
return data
.filter(item => {
// Dynamic filtering of terms here
})
.map((item, idx) => <li key={idx}>{item.title}</li>
Inside the filter I'm trying to get a loop through the array and dynamically produce logic similar to this
item.searchFields[0].toLowerCase().includes(term.toLowerCase()) ||
item.searchFields[1].toLowerCase().includes(term.toLowerCase())
But obviously could loop over an infinite number of searchfields/properties
javascript arrays filter
javascript arrays filter
asked Nov 14 '18 at 17:36
Jason McFarlaneJason McFarlane
459210
459210
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
Use Array#some()
Something like
term = term.toLowerCase()
return data
.filter(item => {
return searchFields.some(field => item[field].toLowerCase().includes(term))
}).map(...
add a comment |
Check if some
of the searchFields
match:
// Checks wether a value matches a term
const matches = (value, term) => value.toLowerCase().includes(term.toLowerCase());
// Checks wether one of the fields in the item matcues the term
const itemMatches = (fields, term) => item => fields.some(field => matches(item[field], term);
// Filter the data to only contain items where on of the searchFields matches the term
const result = props.data.filter( itemMatches(props.searchFields, props.term) );
return result.map(item => <li key={idx}>{item.title}</li>);
add a comment |
You can use Array .some
combined with .filter
let result = data.filter(obj =>
searchFields.some(s =>
obj[s] != undefined && obj[s].toLowerCase() === term
));
let data = [
{ id: 1, country: 'Canada', title: 'Some title here' },
{ id: 2, country: 'Australia', title: 'Another title' },
{ id: 3, country: 'Netherlands', title: 'last title' },
], searchFields = ["country", "title"], term = "canada";
let result = data.filter(obj =>
searchFields.some(s =>
obj[s] != undefined && obj[s].toLowerCase() === term
));
console.log(result);
That is really overcomplicating things.
– Jonas Wilms
Nov 14 '18 at 17:49
@JonasWilms Possibly? That's not really a constructive comment. Care to elaborate?
– zfrisch
Nov 14 '18 at 17:55
Thatflag
? I mean you always check all the properties, you could actually exit after the first found.
– Jonas Wilms
Nov 14 '18 at 17:56
@JonasWilms good point. Better?
– zfrisch
Nov 14 '18 at 18:03
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53305885%2fdynamic-array-filtering-by-object-property%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Use Array#some()
Something like
term = term.toLowerCase()
return data
.filter(item => {
return searchFields.some(field => item[field].toLowerCase().includes(term))
}).map(...
add a comment |
Use Array#some()
Something like
term = term.toLowerCase()
return data
.filter(item => {
return searchFields.some(field => item[field].toLowerCase().includes(term))
}).map(...
add a comment |
Use Array#some()
Something like
term = term.toLowerCase()
return data
.filter(item => {
return searchFields.some(field => item[field].toLowerCase().includes(term))
}).map(...
Use Array#some()
Something like
term = term.toLowerCase()
return data
.filter(item => {
return searchFields.some(field => item[field].toLowerCase().includes(term))
}).map(...
edited Nov 14 '18 at 17:46
answered Nov 14 '18 at 17:41
charlietflcharlietfl
139k1389122
139k1389122
add a comment |
add a comment |
Check if some
of the searchFields
match:
// Checks wether a value matches a term
const matches = (value, term) => value.toLowerCase().includes(term.toLowerCase());
// Checks wether one of the fields in the item matcues the term
const itemMatches = (fields, term) => item => fields.some(field => matches(item[field], term);
// Filter the data to only contain items where on of the searchFields matches the term
const result = props.data.filter( itemMatches(props.searchFields, props.term) );
return result.map(item => <li key={idx}>{item.title}</li>);
add a comment |
Check if some
of the searchFields
match:
// Checks wether a value matches a term
const matches = (value, term) => value.toLowerCase().includes(term.toLowerCase());
// Checks wether one of the fields in the item matcues the term
const itemMatches = (fields, term) => item => fields.some(field => matches(item[field], term);
// Filter the data to only contain items where on of the searchFields matches the term
const result = props.data.filter( itemMatches(props.searchFields, props.term) );
return result.map(item => <li key={idx}>{item.title}</li>);
add a comment |
Check if some
of the searchFields
match:
// Checks wether a value matches a term
const matches = (value, term) => value.toLowerCase().includes(term.toLowerCase());
// Checks wether one of the fields in the item matcues the term
const itemMatches = (fields, term) => item => fields.some(field => matches(item[field], term);
// Filter the data to only contain items where on of the searchFields matches the term
const result = props.data.filter( itemMatches(props.searchFields, props.term) );
return result.map(item => <li key={idx}>{item.title}</li>);
Check if some
of the searchFields
match:
// Checks wether a value matches a term
const matches = (value, term) => value.toLowerCase().includes(term.toLowerCase());
// Checks wether one of the fields in the item matcues the term
const itemMatches = (fields, term) => item => fields.some(field => matches(item[field], term);
// Filter the data to only contain items where on of the searchFields matches the term
const result = props.data.filter( itemMatches(props.searchFields, props.term) );
return result.map(item => <li key={idx}>{item.title}</li>);
answered Nov 14 '18 at 17:43
Jonas WilmsJonas Wilms
58.4k43151
58.4k43151
add a comment |
add a comment |
You can use Array .some
combined with .filter
let result = data.filter(obj =>
searchFields.some(s =>
obj[s] != undefined && obj[s].toLowerCase() === term
));
let data = [
{ id: 1, country: 'Canada', title: 'Some title here' },
{ id: 2, country: 'Australia', title: 'Another title' },
{ id: 3, country: 'Netherlands', title: 'last title' },
], searchFields = ["country", "title"], term = "canada";
let result = data.filter(obj =>
searchFields.some(s =>
obj[s] != undefined && obj[s].toLowerCase() === term
));
console.log(result);
That is really overcomplicating things.
– Jonas Wilms
Nov 14 '18 at 17:49
@JonasWilms Possibly? That's not really a constructive comment. Care to elaborate?
– zfrisch
Nov 14 '18 at 17:55
Thatflag
? I mean you always check all the properties, you could actually exit after the first found.
– Jonas Wilms
Nov 14 '18 at 17:56
@JonasWilms good point. Better?
– zfrisch
Nov 14 '18 at 18:03
add a comment |
You can use Array .some
combined with .filter
let result = data.filter(obj =>
searchFields.some(s =>
obj[s] != undefined && obj[s].toLowerCase() === term
));
let data = [
{ id: 1, country: 'Canada', title: 'Some title here' },
{ id: 2, country: 'Australia', title: 'Another title' },
{ id: 3, country: 'Netherlands', title: 'last title' },
], searchFields = ["country", "title"], term = "canada";
let result = data.filter(obj =>
searchFields.some(s =>
obj[s] != undefined && obj[s].toLowerCase() === term
));
console.log(result);
That is really overcomplicating things.
– Jonas Wilms
Nov 14 '18 at 17:49
@JonasWilms Possibly? That's not really a constructive comment. Care to elaborate?
– zfrisch
Nov 14 '18 at 17:55
Thatflag
? I mean you always check all the properties, you could actually exit after the first found.
– Jonas Wilms
Nov 14 '18 at 17:56
@JonasWilms good point. Better?
– zfrisch
Nov 14 '18 at 18:03
add a comment |
You can use Array .some
combined with .filter
let result = data.filter(obj =>
searchFields.some(s =>
obj[s] != undefined && obj[s].toLowerCase() === term
));
let data = [
{ id: 1, country: 'Canada', title: 'Some title here' },
{ id: 2, country: 'Australia', title: 'Another title' },
{ id: 3, country: 'Netherlands', title: 'last title' },
], searchFields = ["country", "title"], term = "canada";
let result = data.filter(obj =>
searchFields.some(s =>
obj[s] != undefined && obj[s].toLowerCase() === term
));
console.log(result);
You can use Array .some
combined with .filter
let result = data.filter(obj =>
searchFields.some(s =>
obj[s] != undefined && obj[s].toLowerCase() === term
));
let data = [
{ id: 1, country: 'Canada', title: 'Some title here' },
{ id: 2, country: 'Australia', title: 'Another title' },
{ id: 3, country: 'Netherlands', title: 'last title' },
], searchFields = ["country", "title"], term = "canada";
let result = data.filter(obj =>
searchFields.some(s =>
obj[s] != undefined && obj[s].toLowerCase() === term
));
console.log(result);
let data = [
{ id: 1, country: 'Canada', title: 'Some title here' },
{ id: 2, country: 'Australia', title: 'Another title' },
{ id: 3, country: 'Netherlands', title: 'last title' },
], searchFields = ["country", "title"], term = "canada";
let result = data.filter(obj =>
searchFields.some(s =>
obj[s] != undefined && obj[s].toLowerCase() === term
));
console.log(result);
let data = [
{ id: 1, country: 'Canada', title: 'Some title here' },
{ id: 2, country: 'Australia', title: 'Another title' },
{ id: 3, country: 'Netherlands', title: 'last title' },
], searchFields = ["country", "title"], term = "canada";
let result = data.filter(obj =>
searchFields.some(s =>
obj[s] != undefined && obj[s].toLowerCase() === term
));
console.log(result);
edited Nov 14 '18 at 18:02
answered Nov 14 '18 at 17:46
zfrischzfrisch
4,55511024
4,55511024
That is really overcomplicating things.
– Jonas Wilms
Nov 14 '18 at 17:49
@JonasWilms Possibly? That's not really a constructive comment. Care to elaborate?
– zfrisch
Nov 14 '18 at 17:55
Thatflag
? I mean you always check all the properties, you could actually exit after the first found.
– Jonas Wilms
Nov 14 '18 at 17:56
@JonasWilms good point. Better?
– zfrisch
Nov 14 '18 at 18:03
add a comment |
That is really overcomplicating things.
– Jonas Wilms
Nov 14 '18 at 17:49
@JonasWilms Possibly? That's not really a constructive comment. Care to elaborate?
– zfrisch
Nov 14 '18 at 17:55
Thatflag
? I mean you always check all the properties, you could actually exit after the first found.
– Jonas Wilms
Nov 14 '18 at 17:56
@JonasWilms good point. Better?
– zfrisch
Nov 14 '18 at 18:03
That is really overcomplicating things.
– Jonas Wilms
Nov 14 '18 at 17:49
That is really overcomplicating things.
– Jonas Wilms
Nov 14 '18 at 17:49
@JonasWilms Possibly? That's not really a constructive comment. Care to elaborate?
– zfrisch
Nov 14 '18 at 17:55
@JonasWilms Possibly? That's not really a constructive comment. Care to elaborate?
– zfrisch
Nov 14 '18 at 17:55
That
flag
? I mean you always check all the properties, you could actually exit after the first found.– Jonas Wilms
Nov 14 '18 at 17:56
That
flag
? I mean you always check all the properties, you could actually exit after the first found.– Jonas Wilms
Nov 14 '18 at 17:56
@JonasWilms good point. Better?
– zfrisch
Nov 14 '18 at 18:03
@JonasWilms good point. Better?
– zfrisch
Nov 14 '18 at 18:03
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53305885%2fdynamic-array-filtering-by-object-property%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown