使用多个字符串过滤JavaScript数组

4

我正试图过滤一个名为products的数组,该数组中填充了每个产品的一个字符串。

var products = [
    'canadian black angus beef fresh',
    'canadian black angus beef frozen',
    'american black angus beef frozen'
];

搜索始于将表单输入元素按空格分割成一个名为 keywords 的数组,其中包含变长字符串。
var keywords = ['angus', 'fresh'];

实际上,我正在使用for循环遍历product_array,并为keyword_array创建第二个(内部)for循环。到目前为止一切都好。

这是展示问题的简短代码:

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'
    */
}

我该如何解决这个问题?


1
对不起,我不清楚你想要什么! - LcSalazar
4个回答

2
首先,您应该查看.filter()函数。它遍历数组,并根据您设置的条件的true/false返回项。

MDN关于Array.prototype.filter()的文档

现在,为了确保两个关键字都存在,您可以使用一些标志来指示它是否存在:
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;
});

谢谢@LcSalazar,这将会很有帮助。 - Jignesh Raval

1

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();


嗨@Mandera,你的解决方案对我很有效。感谢你分享这个。如果可能的话,你能否使用Array.map或Array.filter方法提供相同的功能呢? - Jignesh Raval
太好了听到这个消息,但恐怕我不知道那些方法如何工作,希望其他人能帮助你。 - Mandera

1

只需放置一个标志来检查是否具有所有关键字:

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]);
}

请查看这个代码片段: http://jsfiddle.net/eoz1y8n4/


+1 哦,是的。这是一个更好的选择! - Mithun Satheesh

0

这个帖子对我在搜索方面取得了很大的帮助,基于此,我已经扩展了上述给出的解决方案,以便在对象数组和多个字段(如标题、类别或标签)中进行搜索。

我会附上代码来回答问题,以便在需要时为任何开发人员提供帮助。仍有进一步改进的机会,我希望这对某些人有所帮助。

我的要求是:

  • 在标题(字符串)、类别(字符串)或标签数组(字符串数组)中查找搜索词。
  • 搜索词可以是用空格分隔的多个单词,例如"Es6 IIFE"
  • 搜索词可以以任何顺序出现在字符串中的任何位置

我已经为此准备了一个实时演示。您可以运行并检查结果。

我有以下包含文章列表的样本对象数组。

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"] },
        ];

如果有人在搜索框中输入“es6 iife”并按下按钮,它将首先查找标签数组,如果在那里找不到,则会查找标题和类别。

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>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接