Javascript 使用值数组筛选多个属性的值

Javascript 使用值数组筛选多个属性的值,javascript,json,underscore.js,filtering,lodash,Javascript,Json,Underscore.js,Filtering,Lodash,所以我真的想复制我以前的版本,因为我不能很好地解释我自己,因此没有得到答案(也没有真正解决我的问题) 这里有一个JSON: [ { "id": 2, "name": "Google", "country": "Sweden" }, { "id": 3, "name": "Google", "country": "USA" }, { "id": 9, "name": "Google", "country":

所以我真的想复制我以前的版本,因为我不能很好地解释我自己,因此没有得到答案(也没有真正解决我的问题)

这里有一个JSON:

[
  {
    "id": 2,
    "name": "Google",
    "country": "Sweden"
  },
  {
    "id": 3,
    "name": "Google",
    "country": "USA"
  },
  {
    "id": 9,
    "name": "Google",
    "country": "Ukraine"
  },
  {
    "id": 10,
    "name": "Bing",
    "country": "Sweden"
  }
]
我想我之前没能做的就是把我目前所拥有的东西发布出来,更好地解释我需要什么。这就是我现在拥有的:

 $scope.loadSearchEngines = function ($query) {
     return $http.get('search-engines.json', {cache: true}).then(function (response) {
         var tags = response.data;
         return tags.filter(function (tag) {
             return tag.name.toLowerCase().indexOf($query.toLowerCase()) != -1;
         });
     });
 };
此筛选器限制我仅搜索
名称
属性,而理想情况下我希望搜索任何属性(或者更确切地说,搜索所有属性),并且我希望筛选器使用一个参数数组,以便每个单词分别查找对象中的每个属性并找到匹配项

在上一篇文章中,一个人为它发布了一个for循环,但这正是我想要避免的那种不直观的事情。 我知道我想要的结果是什么,但我就是想不出一种方法(lodash/下划线似乎几乎可以做到这一点,但我认为在某些地方缺少了一些东西,或者我真的不善于理解文档)

示例:

如果我写“GoogleSweden”,它将只显示1个结果,如果我写“sweden”,它将显示来自google和bing的结果。 如果我写“In”,我想应该显示“bINg”和谷歌“ukraINe”


一开始这看起来不那么麻烦,但我不能用过滤器来解决这个问题。我真的没有任何想法可以发布,因为它们糟糕得让人难堪,这对我来说真的是一个灰色地带。

版本a将整个数据集的结果塑造成想要的集,通过搜索词进行迭代

var数据=[{
“id”:2,
“名称”:“谷歌”,
“国家”:“瑞典”
}, {
“id”:3,
“名称”:“谷歌”,
“国家”:“美国”
}, {
“id”:9,
“名称”:“谷歌”,
“国家”:“乌克兰”
}, {
“id”:10,
“姓名”:“必应”,
“国家”:“瑞典”
}];
功能搜索{
var searchA=s.split(“”).map(函数(a){返回a.toLowerCase();});
var result=JSON.parse(JSON.stringify(data));
searchA.forEach(函数(a){
结果=结果.reduce(函数(res,el){
var i;
对于(我在el中){
if((“”+el[i]).toLowerCase().indexOf(a)){
推力(el);
打破
}
}
返回res;
}, []);
});
返回结果;
}
out('search for'google sweden\'\n'+JSON.stringify(search('google sweden'),null,4),true);
out('search for'bing\'\n'+JSON.stringify(search('bing'),null,4),true);
out('search for'IN\'\n'+JSON.stringify(search('IN'),null,4),true);
out('search for'x\'\n'+JSON.stringify(search('x'),null,4),true);
功能输出(s、pre){
var descriptionNode=document.createElement('div');
如果(预){
var preNode=document.createElement('pre');
preNode.innerHTML=s+'
'; descriptionNode.appendChild(preNode); }否则{ descriptionNode.innerHTML=s+'
'; } document.getElementById('out0').appendChild(descriptionNode); }

可能是这样的(注意,可能不是最有效的)。不处理小写,但添加起来很简单


从问题看,似乎您想要筛选一个列表,其中每个项目中的值都包含每个关键字:

    var keywords = ['Google', 'Sweden'];

    var result = _.filter(data, function(item){
        return _.every(keywords, function(keyword){
            return _.some(item, function(value){
                return _.isString(value) && value.indexOf(keyword) != -1;
            })
        });
    });

您想在所有对象的值中搜索关键字吗?这里的问题仍然是“google sweden”应该只显示与google和sweden匹配的答案,因此它应该只显示一个结果。与另一个答案相同,如果键入2个单词,它应该与google和sweden匹配,否则,如果我有20个不同的Bing和20个不同的Google,它会显示所有的Bing和Google,这就是我想要避免的。输入“google sweden”应该只显示一个结果。现在你可以得到一个匹配所有参数的搜索结果(而不是OR)。嗯,这正是我需要的。如果您有时间并且愿意解释for循环和
found===searchA.length&&res.push(el)是如何找到的部分工作,这将是可怕的,以及(在一天结束时,学习做这件事,并了解它自己是为什么我在这里)。我猜
some
和这行
~(''+el[I]).toLowerCase().indexOf(a)
对我来说是不熟悉的,我从未见过/使用过这样的东西
读取
if(found==searchA.length){res.push(el);}
。比较检查所需单词的最长长度是否与找到的单词相等
Array.some()
正在返回
true
,如果回调返回
true
(可以是比较或其他内容)
~(''+el[i]).toLowerCase().indexOf(a)
el[i]
转换为字符串,应用小写并在内部查找
a
的索引。波浪号将按位not应用于值,因此
-1
(非字符串)计算为
false
(=~-1=0),所有其他值计算为
true
,此处使用。这太棒了!我做了一个改变,让它变得更好。如果将字符串规范化为大写,则搜索不区分大小写<代码>value.toUpperCase().indexOf(关键字.toUpperCase())!=-1;
    var keywords = ['Google', 'Sweden'];

    var result = _.filter(data, function(item){
        return _.every(keywords, function(keyword){
            return _.some(item, function(value){
                return _.isString(value) && value.indexOf(keyword) != -1;
            })
        });
    });