[英]Search/Filter JavaScript Object Array
我正在尝试创建一个搜索/过滤器函数,它允许用户过滤一个 JS 对象数组,该数组返回一个填充了与搜索查询匹配的数据的数组。
例如,我希望能够在一个查询中搜索多个属性; 如果我搜索HKG
,它将返回所有 3 个对象,但如果我搜索HKG 12345
,它将返回数组中的第一个对象。
另一个示例是,如果我要搜索8
,它将从与查询匹配的sumOfContainers
属性返回数组中的前 2 个对象,但如果我搜索8 SAV
,它将仅返回第一个对象。
results = [];
objects = [
{laneId:"12345", lane:"HKG-SAV", equipmentType:"20'STD", sumOfContainers: "8", baseline:"$1234", new:"$1234", newSaving:"$1234"},
{laneId:"12346", lane:"HKG-FRA", equipmentType:"20'STD", sumOfContainers: "8", baseline:"$1234", new:"$1234", newSaving:"$1234"},
{laneId:"12347", lane:"HKG-LAX", equipmentType:"20'STD", sumOfContainers: "9", baseline:"$1234", new:"$1234", newSaving:"$1234"},
];
const Search = (toSearch) => {
for(var i=0; i<objects.length; i++) {
for(key in objects[i]) {
if(objects[i][key].indexOf(toSearch)!=-1) {
results.push(objects[i]);
}
}
}
}
我尝试的问题是它会返回重复的数据。 我在网上遇到了很多帖子,但我发现很难找到寻求类似结果的帖子。
我正在尝试使用本机 JavaScript 来实现这一点。
一些问题:
添加重复项是因为在添加对象后,您会继续在同一对象中寻找更多匹配项。 所以如果有任何其他键匹配,相同的对象将被添加两次
当搜索包含空格时,您的描述说您希望将其视为多个搜索词的分隔符,但您的代码永远不会像那样拆分搜索参数。
您的函数中没有return
语句
关键变量没有用var
、 let
或const
我建议用filter
解决这个问题:这保证你不会得到重复。 然后要求所有搜索词都匹配:为此,您可以使用split
和every
。 然后要求至少有一个与搜索词匹配的键:为此,您可以使用some
:
不要用 PascalCase 命名你的搜索函数,而是用驼峰命名(所以用search
而不是Search
)。 通常的做法是 PascalCase 保留用于构造函数/类名称。
const search = toSearch => {
let terms = toSearch.split(" ");
return objects.filter(object =>
terms.every(term =>
Object.values(object).some(value =>
value.includes(term)
)
)
);
}
我想出了一种非常糟糕的方法来实现问题中的条件。 如果有人可以使此代码更加优化,那就太棒了。
const search = () => {
let toSearch = document.getElementById("search").value;
let lanes = this.objects;
let result = [];
const filters = toSearch.split(" ");
for(let i = 0; i <lanes.length; i++) {
let search = "";
let isMatched = true;
for(let key in lanes[i]) {
search += lanes[i][key] + " ";
}
filters.forEach(filter => {
if(search.indexOf(filter) == -1) {
isMatched = false;
break;
}
});
if(isMatched) {
result.push(lanes[i]);
}
}
return result;
}
如果你不介意lodash :
const _ = require('lodash');
const objects = [
{laneId:"12345", lane:"HKG-SAV", equipmentType:"20'STD", sumOfContainers: "8", baseline:"$1234", new:"$1234", newSaving:"$1234"},
{laneId:"12346", lane:"HKG-FRA", equipmentType:"20'STD", sumOfContainers: "8", baseline:"$1234", new:"$1234", newSaving:"$1234"},
{laneId:"12347", lane:"HKG-LAX", equipmentType:"20'STD", sumOfContainers: "9", baseline:"$1234", new:"$1234", newSaving:"$1234"},
];
const mySearch = (arr, text) => {
const includesValue = (word, obj) => _.some(obj, (value) => _.includes(value, word));
const words = _.words(text);
return arr
.filter((obj) =>
words.every((word) =>
includesValue(word, obj)
)
);
};
console.log(mySearch(objects, 'HKG 12345'));
// [{laneId: '12345', lane: 'HKG-SAV', equipmentType: "20'STD", sumOfContainers: '8', baseline: '$1234', new: '$1234', newSaving: '$1234' }]
console.log(mySearch(objects, '8'));
// [
// {laneId:"12345", lane:"HKG-SAV", equipmentType:"20'STD", sumOfContainers: "8", baseline:"$1234", new:"$1234", newSaving:"$1234"},
// {laneId:"12346", lane:"HKG-FRA", equipmentType:"20'STD", sumOfContainers: "8", baseline:"$1234", new:"$1234", newSaving:"$1234"},
// ]
console.log(mySearch(objects, '8 SAV'));
// [{laneId: '12345', lane: 'HKG-SAV', equipmentType: "20'STD", sumOfContainers: '8', baseline: '$1234', new: '$1234', newSaving: '$1234' }]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.