Javascript 如何使用筛选器在数组中搜索对象的多个键值?

Javascript 如何使用筛选器在数组中搜索对象的多个键值?,javascript,arrays,vue.js,filtering,vuejs2,Javascript,Arrays,Vue.js,Filtering,Vuejs2,我有一个葡萄酒数组,其中包含每个葡萄酒的数据对象: var wines = [ { _id: '59a740b8aa06e549918b1fda', wineryName: 'Some Winery', wineName: 'Pinot Noir', wineColor: 'Red', imageLink: '/img/FortBerensPN.png' }, { _id: '59a7410aaa06e549918b1fdb', wineryNam

我有一个葡萄酒数组,其中包含每个葡萄酒的数据对象:

var wines = [
  { _id: '59a740b8aa06e549918b1fda',
    wineryName: 'Some Winery',
    wineName: 'Pinot Noir',
    wineColor: 'Red',
    imageLink: '/img/FortBerensPN.png' },
  { _id: '59a7410aaa06e549918b1fdb',
    wineryName: 'Some Winery',
    wineName: 'Pinot Gris',
    wineColor: 'White',
    imageLink: '/img/FortBerensPG.png' },
  { _id: '59a74125aa06e549918b1fdc',
    wineryName: 'Some Winery',
    wineName: 'Rose',
    wineColor: 'Rose',
    imageLink: '/img/FortBerensRose.png' },
  { _id: '59a74159aa06e549918b1fdd',
    wineryName: 'Some other Winery',
    wineName: 'Rose',
    wineColor: 'Rose',
    imageLink: '/img/FortBerensRose.png' },
  { _id: '59a7417aaa06e549918b1fde',
    wineryName: 'Some other Winery',
    wineName: 'Pinot Gris',
    wineColor: 'White',
    imageLink: '/img/FortBerensPG.png' },
  { _id: '59a8721f4fd43b676a1f5f0d',
    wineryName: 'Some other Winery',
    wineName: 'Pinot Gris',
    wineColor: 'White',
    imageLink: '/img/FortBerensPG.png' },
  { _id: '59a872244fd43b676a1f5f0e',
    wineryName: 'Winery 3',
    wineName: 'Pinot Noir',
    wineColor: 'Red',
    imageLink: '/img/FortBerensPN.png' } ]
我可以找出如何搜索wine对象(不区分大小写),同时指定要搜索对象的哪个键,如下所示:

var search = 'Noir'

filteredWines = function () {
  return wines.filter(function(wine){
    return (wine.wineName.toLowerCase().indexOf(search.toLowerCase())>=0;
  });
};
返回:

[ { _id: '59a740b8aa06e549918b1fda',
    wineryName: 'Some Winery',
    wineName: 'Pinot Noir',
    wineColor: 'Red',
    imageLink: '/img/FortBerensPN.png' },
  { _id: '59a872244fd43b676a1f5f0e',
    wineryName: 'Winery 3',
    wineName: 'Pinot Noir',
    wineColor: 'Red',
    imageLink: '/img/FortBerensPN.png' } ]
但是,如果
var-search='Winery 3'
var-search='red'
则它显然不会返回任何结果,因为它正在查找数组中每个对象的
wineName
的值

那个么,有并没有一种方法可以使用过滤器(或其他方法?)来搜索所有键值,或者更好的是,搜索多个指定键值并返回匹配对象的数组

比如:

filteredWines = function () {
  return wines.filter(function(wine){
    return ((wine.wineName.toLowerCase() && wine.wineName.toLowerCase() 
          && wine.wineName.toLowerCase()).indexOf(search.toLowerCase())>=0;
  });
};
还是我完全找错人了


另外,我正在使用Vue.js2,所以如果在Vue中有更好的方法,我会洗耳恭听

过滤器工作正常。哎呀,我把问题看得更仔细了。过滤器仍然可以工作,但您也必须过滤这些值

让葡萄酒=[
{
_id:'59a740b8aa06e549918b1fda',
酒庄名称:“某个酒庄”,
酒名:“黑比诺”,
wineColor:‘红色’,
imageLink:“/img/FortBerensPN.png”
},
{
_id:'59a7410aaa06e549918b1fdb',
酒庄名称:“某个酒庄”,
酒名:“灰比诺”,
wineColor:'白色',
imageLink:“/img/FortBerensPG.png”
},
{
_id:'59a74125aa06e549918b1fdc',
酒庄名称:“某个酒庄”,
酒名:“玫瑰”,
wineColor:‘玫瑰’,
imageLink:“/img/FortBerensRose.png”
},
{
_id:'59a74159aa06e549918b1fdd',
酒庄名称:“其他酒庄”,
酒名:“玫瑰”,
wineColor:‘玫瑰’,
imageLink:“/img/FortBerensRose.png”
},
{
_id:'59a7417aaa06e549918b1fde',
酒庄名称:“其他酒庄”,
酒名:“灰比诺”,
wineColor:'白色',
imageLink:“/img/FortBerensPG.png”
},
{
_id:'59a8721f4fd43b676a1f5f0d',
酒庄名称:“其他酒庄”,
酒名:“灰比诺”,
wineColor:'白色',
imageLink:“/img/FortBerensPG.png”
},
{
_id:'59a872244fd43b676a1f5f0e',
酒庄名称:“酒庄3”,
酒名:“黑比诺”,
wineColor:‘红色’,
imageLink:“/img/FortBerensPN.png”
}
];
让搜索=(val)=>wines.filter(w=>Object.values(w).filter(v=>v.toLowerCase().indexOf(val.toLowerCase())!=-1.length>0);

console.log(搜索('some'))您可以使用一个更通用的函数来扫描字符串的所有属性。使用
Object.values()
循环遍历所有属性值,并在找到匹配项后立即使用
some

filteredWines = function (search) {
    var lowSearch = search.toLowerCase();
    return wines.filter(function(wine){
        return Object.values(wine).some( val => 
            String(val).toLowerCase().includes(lowSearch) 
        );
    });
}
如果您希望传递特定键以进行搜索,请执行以下操作:

filteredWines = function (search, keys) {
    var lowSearch = search.toLowerCase();
    return wines.filter(function(wine){
        return keys.some( key => 
            String(wine[key]).toLowerCase().includes(lowSearch) 
        );
    });
}
称为

filteredWines('Winery 3', ['wineryName', 'wineName']);

我还建议尝试更普遍的方法:

function getMatchingWhine(keys, searchTerm, wines) {

  function extractTextFromKeys(keys, object) {
    let text = '';
    keys.forEach(key => {
        text += ' ' + object[key];
    });
    return text.toLowerCase();
  }

  return wines.filter(wine => {
    const relevantText = extractTextFromKeys(keys, wine);
    return relevantText.includes(searchTerm.toLowerCase());
  });
}

也可以这样做:

    this.wines = this.wines.filter((item) => {
                return (item.wineryName.toString().toLowerCase().indexOf(val.toLowerCase()) > -1 ||
                item.wineName.toLowerCase().indexOf(val.toLowerCase()) > -1 ||
                item.wineColor.toLowerCase().indexOf(val.toLowerCase()) > -1);
            })
使用“trincot”中的解决方案,并将angular5应用程序的解决方案更改为:

filter(search, list): Observable<IFilteredList> {
  return list.filter(item => {
    return Object.values(item).some(val =>
      String(val).includes(search)
    );
  })
}
过滤器(搜索,列表):可观察{
返回列表。筛选器(项=>{
返回Object.values(item).some(val=>
字符串(val).includes(搜索)
);
})
}

是否应在每个属性中搜索一个值?或者您是否为每个属性指定了不同的搜索值?也许我误解了您的问题,但我认为简单地使用Or运算符就可以了?您可以通过创建一个函数
(wine.wineName.toLowerCase().indexOf(search.toLowerCase())>=0
)来清理此部分。或者,您可以使用regex.BTW,从人们最终发布的任何筛选方法中选择,但在Vue中使用它将是一种理想的方式。@Bert我正在将其填充到计算属性中并返回结果:)不过,谢谢你让其他人明白这一点!太棒了,谢谢!再次感谢@Bert为我精心制作的视频:)