【问题标题】:Filter multiple array object with multiple property过滤具有多个属性的多个数组对象
【发布时间】:2018-05-30 03:23:21
【问题描述】:

我正在尝试创建一个过滤器函数,它可以从给定的字符串键集中返回与我正在寻找的值匹配的数据结果

数组示例:

let data = [
 { id:1 , data:{ name:"sample1",address:{ cat:"business" } } },
 { id:2 , data:{ name:"sample2",address:{ cat:"office"  }  } },
 { id:3 , data:{ name:"sample3",address:{ cat:"office"  } } },
 { id:4 , data:{ name:"sample4",address:{ cat:"office"  }  } }
 { id:5 , data:{ name:"sample5",address:{ cat:"home"  } } }
 { id:6 , data:{ name:"sample6",address:{ cat:"home"  }  } }
]



function filter( collection , value ,key ){
  //code 
}


let result = filter( data , "business" , [ "data","address","cat" ] )

console.log(result)

预期结果是

{ id:1 , data:{ name:"sample1",address:{ cat:"business" } } },

【问题讨论】:

  • 你想搜索任何一个key,对吧?意思是说,有时候key可能也是id,name,address
  • 没有键是数组中值的确切地址。它也可以是字符串或对象,你可以修改它。
  • 非常好的问题

标签: javascript typescript underscore.js lodash


【解决方案1】:

您可以使用filter 搜索数据。使用reduce 构造密钥。

注意:filter 返回匹配元素的数组。如果你只喜欢第一个匹配,你可以使用find

const data = [
  { id: 1, data: { name: "sample1", address:{ cat: "business" } } },
  { id: 2, data: { name: "sample2", address:{ cat: "office" } } },
  { id: 3, data: { name: "sample3", address:{ cat: "office" } } },
  { id: 4, data: { name: "sample4", address:{ cat: "office" } } },
  { id: 5, data: { name: "sample5", address:{ cat: "home" } } },
  { id: 6, data: { name: "sample6", address:{ cat: "home" } } }
]

const filter = (collection, keys, value) => 
  collection.filter(o => keys.reduce((c, v) => c[v] || {}, o) === value)
const result = filter(data, ["data", "address", "cat"], "business")

console.log(result)

【讨论】:

  • 可能有助于记下有关返回数组而不是单个项目的注释
  • 这是一个正在寻找的人,谢谢 Eddie .. 它非常原生 .. 不需要 lodash .. :)
  • Crazometer,你说得对。我在上面注意到了。 @JakeGarbo 乐于助人:)
【解决方案2】:
function filter( collection , value ,key ){
  const getNestedObjectValue = (nestedObject, propertyPath) => {
      return propertyPath.reduce((obj, key) =>
          (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObject);

  };
  return collection.filter( item => getNestedObjectValue(item, key) === value);
}

过滤器函数将在匹配时返回一个匹配对象的数组,在没有匹配时返回一个空数组

let result = filter( data , "business" , [ "data","address","cat" ] );

console.log(result); // [{"id":1,"data":{"name":"sample1","address":{"cat":"business"}}}]

let result2 = filter( data , "office" , [ "data","address","cat" ] );

console.log(result2); //[{"id":2,"data":{"name":"sample2","address":{"cat":"office"}}},{"id":3,"data":{"name":"sample3","address":{"cat":"office"}}},{"id":4,"data":{"name":"sample4","address":{"cat":"office"}}}]

let result3 = filter( data , "vacation" , [ "data","address","cat" ] );

console.log(result2); // [] 

【讨论】:

    【解决方案3】:

    你可以试试下面的代码。

    如果它不能满足您的问题,或者您想在代码中添加更多功能,请发表评论。我会更新我的答案。

    function filter( collection , value ,key ){
         for(var obj of collection) {
               if(obj[key[0]][key[1]][key[2]] == value)
               { 
                   return obj
               }
         }
         return null;
    }
    

    【讨论】:

    • 感谢兄弟的帮助,但这个答案不能是动态的..例如密钥只有 1 或 2。
    • 好的,你能添加2-3个预期输出的测试用例吗?我很快就会把它变成动态的。谢谢。
    【解决方案4】:

    使用下划线和 ES6 箭头符号清洁代码。

    const equalTo = expected => actual => expected === actual;
    
    function filterDeepValue(collection, value, path) {
        const criterion = _.compose(equalTo(value), _.property(path));
        return _.filter(collection, criterion);
    }
    
    const data = [
        {id: 1, data: {name: "sample1", address: {cat: "business"}}},
        {id: 2, data: {name: "sample2", address: {cat: "office"}}},
        {id: 3, data: {name: "sample3", address: {cat: "office"}}},
        {id: 4, data: {name: "sample4", address: {cat: "office"}}},
        {id: 5, data: {name: "sample5", address: {cat: "home"}}},
        {id: 6, data: {name: "sample6", address: {cat: "home"}}},
    ];
    
    console.log(filterDeepValue(data, 'business', ['data', 'address', 'cat']));
    <script src="https://underscorejs.org/underscore-umd-min.js"></script>

    【讨论】:

      猜你喜欢
      • 2021-07-07
      • 2019-11-04
      • 1970-01-01
      • 2016-08-03
      • 2018-08-17
      • 2021-07-05
      • 2017-11-03
      • 2019-08-03
      • 1970-01-01
      相关资源
      最近更新 更多