Meteor随机排序集合

5
我希望从Meteor集合中获取一个随机排序的集合。什么是最好/最有效的方法? Mongo选项存在争议
我目前正在使用underscore _.shuffle,非常整洁,例如:
Template.userList.helpers({
  users: function() {
    return _.shuffle(Meteor.users.find().fetch());
  }
});

我使用Jade,所以可能在模板层面有一个选项?

问题:由于您在模板中使用的是数组而不是游标,因此它仍然具有响应性吗? - Kyll
@Kyll,是的,但如果对集合进行更新,则整个辅助程序将被重新计算,因此没有很好的细粒度更新,这可能是一个问题或不是问题。 - Peppe L-G
这是我找到的最佳解决方案,我认为没有更好的方法来实现相同的效果。 - svelandiag
1个回答

0
你可以这样使用 Lodash _.shuffle
Template.userList.helpers({
  users: function() {
    return _.shuffle(Meteor.users.find().fetch());
  }
});

虽然这听起来很有趣,但在底层确实存在差异:

Underscore (source)

_.shuffle = function(obj) {
  var set = isArrayLike(obj) ? obj : _.values(obj);
  var length = set.length;
  var shuffled = Array(length);
  for (var index = 0, rand; index < length; index++) {
    rand = _.random(0, index);
    if (rand !== index) shuffled[index] = shuffled[rand];
    shuffled[rand] = set[index];
  }
  return shuffled;
};

Lo-Dash(稍作修改以便于比较,来源

_.shuffle = function(collection) {
  MAX_ARRAY_LENGTH = 4294967295;
  return sampleSize(collection, MAX_ARRAY_LENGTH);
}

function sampleSize(collection, n) {
  var index = -1,
      result = toArray(collection),
      length = result.length,
      lastIndex = length - 1;

  n = clamp(toInteger(n), 0, length);
  while (++index < n) {
    var rand = baseRandom(index, lastIndex),
        value = result[rand];

    result[rand] = result[index];
    result[index] = value;
  }
  result.length = n;
  return result;
}

您可以查看此SO讨论,以深入比较这两个库。

Underscore和Lo-Dash都使用Fisher-Yates shuffle,您很难做得比它们更好。


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