如何使用_.filter按名称和排名进行排序?

时间:2014-03-23 22:20:15

标签: javascript jquery underscore.js

我有以下内容:

Emojis = {
  ':smile:' : { people: true, ranking: 1 },
  ':gring:' : { people: true, ranking: 2 },
  ':wink:' : { people: true, ranking: 3 },
  ':smirk:' : { people: true }
};

EmojiNames = _.keys(Emojis);

EmojiCommon = _.filter(EmojiNames, function (name) {
  if (Emojis[name].people) {
    return name;
  } else {
    return false;
  }
});

现在,我有EmojiCommon,返回与名称匹配的项目==" people"如何让EmojiCommon功能也按排名过滤。第1项是第一项,没有排名的项目是否排在所有具有排名的项目之下?

由于

2 个答案:

答案 0 :(得分:2)

您必须添加额外的步骤才能进行排序。这首先按等级排序,然后按名称排序。您可以将||的参数反转为按名称排序,然后按排名。

Emojis = {
  ':wink:' : { people: true, ranking: 3 },
  ':gring:' : { people: true, ranking: 2 },
  ':smirk:' : { people: true },
  ':smile:' : { people: true, ranking: 1 }
};

EmojiNames = _.keys(Emojis);

EmojiCommon = _.filter(EmojiNames, function (name) {
  return Emojis[name].people;
});

EmojiCommon.sort(function(a,b) {
  var rankA = Emojis[a].ranking || Number.MAX_VALUE;
  var rankB = Emojis[b].ranking || Number.MAX_VALUE;
  return (rankA - rankB) || (a > b ? 1 : -1);
});

console.log(EmojiCommon)
a中的{p> b.sort是字符串。如果将两个字符串与<进行比较,则会按字母顺序进行比较。

答案 1 :(得分:0)

在JavaScript中,对象没有任何订购保证。那么你真正想要的是一个阵列。你有几个选择。您可以使用数组开始:

var emojis = [
    { key: ':smile:', people: true, ranking: 1 },
    { key: ':gring:', people: true, ranking 2 },
    { key: ':wink:', people: true, ranking: 3 },
    { key: ':smirk:', people: true }
];

然后你可以过滤&amp;分类:

var filtered = emojis.filter(function(x) { return x.people; });
filtered.sort(function(a,b) { return a.ranking - b.ranking });

如果您坚持使用对象(即,您还有很多其他代码依赖于此对象),则可以使用Underscore的pairs方法将其转换为数组:

var emojis = _.pairs(Emojis);

然后你只需要一些额外的间接:

var filtered = emojis.filter(function(x) { return x[1].people; });
filtered.sort(function(a,b) { return a[1].ranking - b[1].ranking });

请注意,没有必要使用Underscore的filter方法:内置的JavaScript filter方法适用于您的应用程序。

在评论中,它指出Array.prototype.filter是一个ES5.1功能,所以如果你需要支持真正的旧浏览器(IE8或以下是值得注意的例子),你必须填充它:< / p>

if(!Array.prototype.filter) Array.prototype.filter = function(f,t){
    var ret = [];
    for(var i=0; i<this.length; i++){
        if (t===undefined?f(this[i]):f.call(t,this[i])) {
            ret.push(this[i]);
        }
    }
    return ret;
}