使用多个属性过滤多个数组对象

4

我是一名帮助翻译文本的助手。

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

数组示例:

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:"样本1",address:{ cat:"商业" } } },


你想搜索任何一个关键字,对吗?也就是说,有时候关键字可能是 id、name、address 等? - hygull
不,关键是数组中值的确切地址。它也可以是字符串或对象,您可以修改它。 - Jakegarbo
1
非常好的问题。 - Isaac
4个回答

6

您可以使用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)


1
可能需要注意返回数组而不是单个项。 - Crazometer
这正是我所寻找的,谢谢 Eddie。它非常本地化,不需要使用 lodash。 :) - Jakegarbo
1
Crazometer,你说得对。我已经记录在上面了。@JakeGarbo 很高兴能帮忙 :) - Eddie

1
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); // [] 

0

使用Underscore和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>


0
你可以尝试下面的代码。

如果不满足您的问题,或者您希望在代码中增加更多功能,请评论。我会更新我的答案。

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。 - Jakegarbo
好的,请您添加2-3个测试用例和期望输出?我很快就会使它变得动态。谢谢。 - hygull

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接