如何使用过滤器搜索数组中对象的多个键值?

时间:2017-08-31 23:07:27

标签: javascript arrays vue.js filtering vuejs2

我有一系列含有每种葡萄酒数据的葡萄酒:

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

还是我完全咆哮了错误的树?

PS。我正在使用Vue.js 2,所以如果在vue中有更好的方式,那么我就是所有的耳朵!

5 个答案:

答案 0 :(得分:9)

您可以使用更通用的函数来扫描所有字符串的属性。使用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']);

答案 1 :(得分:1)

也可以这样做:

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

答案 2 :(得分:0)

过滤器有效。糟糕,我更仔细地阅读了这个问题。过滤器仍然有效,但您也必须过滤值。

let 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'
    }
];

let search = (val) => wines.filter(w => Object.values(w).filter(v => v.toLowerCase().indexOf(val.toLowerCase()) !== -1).length > 0);

console.log(search('some'));

答案 3 :(得分:0)

我还建议尝试更通用的方法:

3

答案 4 :(得分:0)

使用“trincot”中的解决方案并将其更改为我的angular5应用程序:

filter(search, list): Observable<IFilteredList> {
  return list.filter(item => {
    return Object.values(item).some(val =>
      String(val).includes(search)
    );
  })
}