admin管理员组文章数量:1430017
I'm trying to filter an Array named products which is filled with one string per product.
var products = [
'canadian black angus beef fresh',
'canadian black angus beef frozen',
'american black angus beef frozen'
];
The search starts by splitting an form input element by spaces in an array named keywords which contains an variable length of strings.
var keywords = ['angus', 'fresh'];
Actually I'm for-looping the product_array and make an 2nd (inner) for-loop for the keyword_array. Till now its all fine.
here is my shorten code which shows the issue:
function test() {
var products = [
'canadian black angus beef fresh',
'canadian black angus beef frozen',
'american black angus beef frozen'
];
var keywords = ['angus', 'fresh'];
var hits = [];
for (var i = 0; i < products.length; i++) {
for (var j = 0; j < keywords.length; j++) {
if (products[i].indexOf(keywords[j]) != -1) {
/*
a if case for looped '&&' operator
would be great - or something like that
looped because of the variable length of keywords
*/
hits.push(products[i]);
}
}
}
console.log(hits);
/*
all products :/ - because all product matches with 'angus'
but I'm searching for an product that contains 'angus' && 'fresh'
*/
}
How can I fix this?
I'm trying to filter an Array named products which is filled with one string per product.
var products = [
'canadian black angus beef fresh',
'canadian black angus beef frozen',
'american black angus beef frozen'
];
The search starts by splitting an form input element by spaces in an array named keywords which contains an variable length of strings.
var keywords = ['angus', 'fresh'];
Actually I'm for-looping the product_array and make an 2nd (inner) for-loop for the keyword_array. Till now its all fine.
here is my shorten code which shows the issue:
function test() {
var products = [
'canadian black angus beef fresh',
'canadian black angus beef frozen',
'american black angus beef frozen'
];
var keywords = ['angus', 'fresh'];
var hits = [];
for (var i = 0; i < products.length; i++) {
for (var j = 0; j < keywords.length; j++) {
if (products[i].indexOf(keywords[j]) != -1) {
/*
a if case for looped '&&' operator
would be great - or something like that
looped because of the variable length of keywords
*/
hits.push(products[i]);
}
}
}
console.log(hits);
/*
all products :/ - because all product matches with 'angus'
but I'm searching for an product that contains 'angus' && 'fresh'
*/
}
How can I fix this?
Share Improve this question edited Jul 26, 2020 at 0:18 Jason Aller 3,65228 gold badges41 silver badges39 bronze badges asked Sep 25, 2014 at 13:10 Tarek HaddadTarek Haddad 551 silver badge4 bronze badges 1- 1 I'm sorry, but it's unclear what you want! – LcSalazar Commented Sep 25, 2014 at 13:13
4 Answers
Reset to default 2First of all, you should take a look at the .filter()
function. It iterates through an array, and returns the items you want, based on a true/false return of the conditions you set.
MDN's Docs on Array.prototype.filter()
Now, to be sure that both keywords exists, you can use some flag to indicate whether it does or doesn't:
var hits = products.filter(function(item) {
var valid = true;
for (var i = 0; i < keywords.length; i++) {
if (item.indexOf(keywords[i]) === -1) {
valid = false;
}
}
return valid;
});
Just put a flag that check if you have all keywords :
var containsAll;
for (var i = 0; i < products.length; i++) {
// Initialize flag -> guess that this product is correct
containsAll = true;
for (var j = 0; j < keywords.length; j++) {
if (products[i].indexOf(keywords[j]) === -1) {
// This keyword is not matched -> incorrect product
containsAll = false;
break;
}
}
// All products has been matched
if (containsAll) hits.push(products[i]);
}
See this fiddle : http://jsfiddle/eoz1y8n4/
You simply need to make sure that your product has all of the keywords in it:
function test() {
var products = [
'canadian black angus beef fresh',
'canadian black angus beef frozen',
'american black angus beef frozen'];
var keywords = ['angus', 'fresh'];
var hits = [];
for (var i = 0; i < products.length; i++) {
var allKeywordsMatch = true;
for (var j = 0; j < keywords.length; j++) {
if (products[i].indexOf(keywords[j]) === -1) {
allKeywordsMatch = false;
break;
}
}
if (allKeywordsMatch) hits.push(products[i]);
}
alert(hits);
}
test();
This thread helped me lot to achieve desired result in searching and on the basis of this I have extended above given solution to search in Array of objects and in multiple fields like in Title, Category or Tags.
I am posting my answer with code, just to bee helpful if any developer need this in such case. Still there are chances for further improvements and I hope this will be helpful to someone.
My requirement was :
- To find search words either in Title (String), Category (String) or Array of Tags(Array of String).
- Search words can be multiple with space separated Ex. "Es6 IIFE"
- Search words can be anywhere in the string in any order
I have prepared one live demo for the same.You can run and check the result.
I have following sample Array of Objects with contains a list of Articles.
let articles = [
{ "title": "ES6 — set, map, weak", "category": "ES6", "tags": ["ES6", "Set", "Map", "Weak"] },
{ "title": "JavaScript Modules: From IIFEs to CommonJS to ES6 Modules", "category": "JavaScript", "tags": ["JavaScript", "Modules", "IIFE", "ES6 Modules"] },
{ "title": "A guide to JavaScript Regular Expressions", "category": "JavaScript", "tags": ["JavaScript", "RegExp", "Regular Expressions"] },
];
If any person types "es6 iife" in Search box and press the button then it will first look into Tags array, if not found there then it will look into Title and Category.
let output = document.querySelector('#output');
let articles = [
{ "title": "ES6 — set, map, weak", "category": "ES6", "tags": ["ES6", "Set", "Map", "Weak"] },
{ "title": "JavaScript Modules: From IIFEs to CommonJS to ES6 Modules", "category": "JavaScript", "tags": ["JavaScript", "Modules", "IIFE", "ES6 Modules"] },
{ "title": "A guide to JavaScript Regular Expressions", "category": "JavaScript", "tags": ["JavaScript", "RegExp", "Regular Expressions"] },
];
let initialContent = '';
articles.map(article => {
initialContent += `<li>
<p><b>Title : </b> ${article.title}</p>
<p><b>Category : </b> ${article.category}</p>
<p><b>Tags : </b> ${article.tags}</p>
</li>`;
});
output.innerHTML = initialContent;
function filter() {
let searchTerm = document.querySelector('#searchBox').value;
let keywords = searchTerm.split(' ');
let articleBySearch = [];
articles.map((article) => {
let allKeywordsMatch = true;
keywords.map((keyword) => {
if (article.tags.some((tag) => tag.toLowerCase().indexOf(keyword.toLowerCase()) !== -1)) {
allKeywordsMatch = true;
} else {
if (article.title.toLowerCase().indexOf(keyword.toLowerCase()) === -1 && article.category.toLowerCase().indexOf(keyword.toLowerCase()) === -1) {
allKeywordsMatch = false;
}
}
});
if (allKeywordsMatch) articleBySearch.push(article);
});
// Display Output in the browser
let htmlContent = '';
articleBySearch.map(article => {
htmlContent += `<li>
<p><b>Title : </b> ${article.title}</p>
<p><b>Category : </b> ${article.category}</p>
<p><b>Tags : </b> ${article.tags}</p>
</li>`;
});
output.innerHTML = htmlContent;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
}
.example {
border: 1px solid rgb(245, 28, 118);
width: 400px;
margin: 0 auto;
padding: 1em;
}
.example #searchBox {
padding: 10px;
border: 1px solid #cccccc;
}
.example #searchBox:focus {
padding: 10px;
border: 1px solid #0059ff;
}
.example button {
padding: 10px;
color: #FFF;
background-color: #0059ff;
border: 1px solid #0059ff;
}
.example ul {
margin: 0;
padding: 0;
list-style: none;
}
.example li {
border: 1px solid #cccccc;
padding: 1em;
margin: 1em 0;
}
<div class="example">
<input type="text" id="searchBox" placeholder="Type your words to search" />
<button onClick="filter()">Click to Filter</button>
<ul id="output"></ul>
</div>
本文标签: Javascript filter array by multiple stringsStack Overflow
版权声明:本文标题:Javascript filter array by multiple strings - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745550651a2662927.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论