我有一个大约30个对象的json数组。这是数组中的一个示例对象:
{
"id": 0,
"name": "Valle",
"activities": "night-life",
"food": "fancy-food",
"sport" : "baseball",
"geoProfile": "artsy",
"priority": 2
}
我正在基于用户输入在页面上构建另一个对象。用户将在单选按钮之间进行选择,在他们做出选择之后,我将有一个对象,例如:
{geoProfile: "artsy", activities: "nature", food: "fancy-food", sport: "cricket"}
我正在使用jQuery的$.each()
方法遍历每个对象,如下所示:
$.each(self.data(), function (i, s) {
if (s.geoProfile == self.prefLocation() &&
s.activities == self.prefActivity() &&
s.food == self.prefFood() &&
s.sport == self.prefSport()) {
optionMatched = s;
return false;
}
});
这将返回一个包含所有四个匹配项的对象,但是如何将具有最多匹配项的json对象返回给用户构建的对象?如果两个匹配,我想查看“priority”属性并返回优先级最低的属性。
答案 0 :(得分:3)
您可以使用Array#map
并使用匹配属性的总和构建一个新数组。
稍后您可以sort with map并使用结果进行排序并获取第一个元素。
var data = [/* your data here */],
search = { geoProfile: "artsy", activities: "nature", food: "fancy-food", sport: "cricket" },
result = data.map(function (a, i) {
return {
count: Object.keys(search).reduce(function (r, k) { return r + +(a[k] === search[k]); }, 0),
priority: a.priority,
index: i
}
});
result.sort(function (a, b) {
return b.count - a.count || a.priority - b.priority;
});
单循环解决方案
var data = [/* your data here */],
search = { geoProfile: "artsy", activities: "nature", food: "fancy-food", sport: "cricket" },
result = data.reduce(function (r, a, i) {
document.write('<pre>' + JSON.stringify(r, 0, 4) + '</pre><hr>');
var o = {
count: Object.keys(search).reduce(function (q, k) { return q + +(a[k] === search[k]); }, 0),
priority: a.priority,
index: i
};
if (!i || o.count > r[0].count || o.count === r[0].count && o.priority < r[0].priority) {
return [o];
}
o.count === r[0].count && o.priority === r[0].priority && r.push(o);
return r;
}, []);
答案 1 :(得分:0)
只需跟踪匹配的数量,并根据是否有更多匹配项更新您选择的匹配项。
var numOfMatches = 0;
$.each(self.data(), function(i, s) {
var matchingProperties = 0;
if (s.geoProfile == self.prefLocation()) {
matchingProperties++;
}
if (s.activities == self.prefActivity()) {
matchingProperties++;
}
if (s.food == self.prefFood()) {
matchingProperties++;
}
if (s.sport == self.prefSport()) {
matchingProperties++;
}
if (matchingProperties === 0 || matchingProperties < numOfMatches) {
return;
}
if (!optionMatched // Grab the first match
|| matchingProperties > numOfMatches // or if more properties match
|| s.priority < optionMatched.priority) { // or the one with a lower priority
optionMatched = s;
numOfMatches = matchingProperties;
}
});
或者您可以使用filter
简化初始计数:
var numOfMatches = 0;
$.each(self.data(), function(i, s) {
var matchingProperties = [
s.geoProfile == self.prefLocation(),
s.activities == self.prefActivity(),
s.food == self.prefFood(),
s.sport == self.prefSport()
].filter(function(val) { return val; }).length;
if (matchingProperties === 0 || matchingProperties < numOfMatches) {
return;
}
if (!optionMatched // Grab the first match
|| matchingProperties > numOfMatches // or if more properties match
|| s.priority < optionMatched.priority) { // or the one with a lower priority
optionMatched = s;
numOfMatches = matchingProperties;
}
});