【问题标题】:filter search in array object, in selected keys在数组对象中过滤搜索,在选定的键中
【发布时间】:2019-09-05 10:41:09
【问题描述】:

我需要一些建议或最好的方法来使用传递的值将其用于数组数据过滤器。 目前,我有

let arrayobject = [
{"name": "apple", "type": "juice-material", "srnum": 123234},
{"name": "cranberry", "type": "desert-material", "srnum": 98989},
{"name": "grapes", "type": "wine-material", "srnum":656565}]

如果我通过apple 那么返回数组将是

[{"name": "apple", "type": "juice-material", "srnum": 123234}]

如果我通过了wine-material 返回结果

{"name": "grapes", "type": "wine-material", "srnum":656565}

对于 srnum 类似,传递它时会给出过滤器数组对象的结果。

目前,

我尝试过使用

_.some(arrayobject, _.unary(_.partialRight(_.includes, passedValue)))

它给出上下文结果,但不可预测。

让我知道过滤数据的最佳方法。 谢谢。

【问题讨论】:

  • 带有 toLowerCase 过滤器data.filter(x => x.title.toLowerCase().includes(term.toLowerCase()))

标签: javascript arrays filter lodash


【解决方案1】:

嗯,我认为你的方法几乎是最好的。但是,您使用_.some,它只会在任何项目匹配时给出布尔结果,如果您将其与_.filter 交换,您可以获得所有匹配的项目,或者您可以更改为_.find 以获得第一个:

let arrayobject = [
  {"name": "apple",     "type": "juice-material",  "srnum": 123234},
  {"name": "cranberry", "type": "desert-material", "srnum": 98989},
  {"name": "grapes",    "type": "wine-material",   "srnum": 656565}
]

function filterByValues(collection, whatToSearchFor) {
  //separating just for easier readability
  let predicate = _.unary(_.partialRight(_.includes, whatToSearchFor));
  
  return _.filter(collection, predicate);
}

//matches a value
console.log(filterByValues(arrayobject, "apple"));
console.log(filterByValues(arrayobject, "wine-material"));
console.log(filterByValues(arrayobject, 98989));

//doesn't match a key
console.log(filterByValues(arrayobject, "name"));
console.log(filterByValues(arrayobject, "type"));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>

话虽如此,@georg 在评论中指出,您可以使用较少的 Lodash 功能重写此代码,只需使用 _.includes 进行简单的回调 - 这 可能 比使用_.partialRight_.unary

let arrayobject = [
  {"name": "apple",     "type": "juice-material",  "srnum": 123234},
  {"name": "cranberry", "type": "desert-material", "srnum": 98989},
  {"name": "grapes",    "type": "wine-material",   "srnum": 656565}
]

function filterByValues(collection, whatToSearchFor) {
  //separating just for easier readability
  let predicate = item => _.includes(item, whatToSearchFor);
  
  return _.filter(collection, predicate);
}

//matches a value
console.log(filterByValues(arrayobject, "apple"));
console.log(filterByValues(arrayobject, "wine-material"));
console.log(filterByValues(arrayobject, 98989));

//doesn't match a key
console.log(filterByValues(arrayobject, "name"));
console.log(filterByValues(arrayobject, "type"));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>

【讨论】:

  • 终于有人费心阅读这个问题了 ;) 虽然我不确定一元/部分级联是否比简单的 _.filter(..., x => _.includes(x, search)) 更具可读性
  • @georg 我也不能说。这对我来说都是一样的,但也许不同的人会有不同的看法。我只是重新使用了 OP 的代码。但你确实有一点,我会把它添加到这个答案中
【解决方案2】:

您可以使用arrayobject.filter() 过滤所需的道具

let arrayobject = [
{"name": "apple", "type": "juice-material", "srnum": 123234},
{"name": "cranberry", "type": "desert-material", "srnum": 98989},
{"name": "grapes", "type": "wine-material", "srnum":656565}]

var res = arrayobject.filter(x => x.name == "apple");
console.log(res);

var res2 = arrayobject.filter(x => x.type == "wine-material");
console.log(res2);

【讨论】:

    【解决方案3】:

    过滤器可以按如下方式应用:

    function filterItems(items, searchVal) {
      return items.filter((item) => Object.values(item).includes(searchVal));
    }
    let arrayobject = [
      { "name": "apple", "type": "juice-material", "srnum": 123234 },
      { "name": "cranberry", "type": "desert-material", "srnum": 98989 },
      { "name": "grapes", "type": "wine-material", "srnum": 656565 }]
    
    
    console.log("Filtered by name: ", filterItems(arrayobject, "apple"));
    console.log("Filtered by type: ", filterItems(arrayobject, "desert-material"));
    console.log("Filtered by srnum: ", filterItems(arrayobject, 656565));

    【讨论】:

      【解决方案4】:

      您可以将 flatMap 与所需的数组一起使用。 只需提供您想要查找的属性。

      在你的情况下是

          let arrayobject = [
          {"name": "apple", "type": "juice-material", "srnum": 123234},
          {"name": "cranberry", "type": "desert-material", "srnum": 98989},
          {"name": "grapes", "type": "wine-material", "srnum":656565}]
          
          var filteredData = getFilterData(arrayobject, 656565);
          console.log(filteredData);
          function getFilterData(array, searchValue){            
                 return array.flatMap(obj => obj)
                        .find(({ name,type,srnum }) => (name === searchValue || type == searchValue) 
                        || srnum == searchValue);            
                  }

      【讨论】:

        【解决方案5】:

        如果要从数组中过滤对象,其中包含键上的任何值,那么您可以直接在每个对象中使用_.includes 从数组中过滤( _.filter)它们。如果您需要查看一组特定的键,只需在将对象传递给包含之前使用 _.pick

        let array = [
                      {id: 1, x: 'XX1', y: 'YY1', z: 'ZZ1'},
                      {id: 2, x: 'XX1', y: 'YY2', z: 'ZZ2'},
                      {id: 3, x: 'ZZ2', y: 'YY3', z: 'ZZ1'},
                    ],
              filterByValue = (a, v) => _.filter(a, e => _.includes(e, v)),
              filterByValueInKeys = (a, v, keys) => _.filter(a, e => _.includes(_.pick(e, keys), v));
              
        console.log('ZZ1: ', filterByValue(array, 'ZZ1'));
        console.log('ZZ2: ', filterByValue(array, 'ZZ2'));
        
        console.log('ZZ1 within x,y: ', filterByValueInKeys(array, 'ZZ1', ['x', 'y']));
        console.log('ZZ2 within x,y: ', filterByValueInKeys(array, 'ZZ2', ['x', 'y']));
        <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

        【讨论】:

          【解决方案6】:

          您可以在数组对象上使用filter()filter() 方法创建一个新数组,其中包含所有通过所提供函数实现的测试的元素。

          arrayobject.filter(data => {
          return (data.name && data.name.includes(value)) ||
                 (data.type && data.type.includes(value)) ||
                 (data.srnum && data.srnum.includes(value))
          })
          

          【讨论】:

            猜你喜欢
            • 2021-12-16
            • 1970-01-01
            • 2018-02-09
            • 1970-01-01
            • 2020-10-09
            • 1970-01-01
            • 2017-03-13
            • 2021-12-12
            • 1970-01-01
            相关资源
            最近更新 更多