简体   繁体   English

Javascript按多个字符串过滤数组

[英]Javascript filter array by multiple strings

I'm trying to filter an Array named products which is filled with one string per product.我正在尝试过滤一个名为products的数组,每个产品填充一个字符串。

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.实际上,我正在对 product_array 进行 for 循环,并为 keyword_array 进行第二个(内部)for 循环。 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?我怎样才能解决这个问题?

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.net/eoz1y8n4/看到这个小提琴: http : //jsfiddle.net/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();

First of all, you should take a look at the .filter() function.首先,您应该看看.filter()函数。 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() MDN 的 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;
});

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 become 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.搜索词可以是多个,以空格分隔 Ex。 "Es6 IIFE" “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.如果有人在搜索框中键入“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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM