2016-07-15 55 views
2

我有一个约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对象?如果两个匹配,我想再查看“优先级”属性并返回优先级最低的属性。

+0

对于初学者来说,你需要通过你的阵列迭代和他们的价值观比较用户输入的内容。你试过什么了? –

+0

@MikeC查看上面的编辑,感谢回复 – JordanBarber

回答

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; 
    }, []); 
+0

感谢您的回复。我想我明白。所以在你的例子中,'data'是我的json对象,'search'是用户创建的对象? – JordanBarber

+0

没错。数据将数组与您拥有的对象保存在一起,并且搜索是需要查找的部分。 –

+0

这是否考虑到优先级值? –

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; 
    } 
});