电子邮件列表/集合shuffle和使用下划线/ lodash配对

时间:2014-09-02 04:15:29

标签: javascript arrays collections underscore.js lodash

我试图改组一系列对象(名称和电子邮件地址),将其变成送礼者 - >接收器配对阵列。每次迭代都会从接收者的集合中移除给予者,因此该集合的每个成员都将获得一个独特的合作伙伴。

我已经使用了lodash并创建了一个mixin。有时它可以工作,有时它会锁定浏览器。也许我在while部分出了问题。

_.mixin({
    ldSanta: function (arr) {
        var ret = [],
            emailListCopy = _.assign(arr),
            receiver = {};
        _.times(_.size(emailListCopy), function (i) {
            receiver = arr[i];
            while (receiver === arr[i]) {
                receiver = _.first(_.shuffle(emailListCopy));
            }
            var pair = {
                'giver': arr[i],
                    'receiver': receiver
            };
            ret[i] = _.extend(pair);
            emailListCopy = _.reject(emailListCopy, function (item) {
                return item.name === receiver.name;
            });
        });
        return ret;
    }
});

例如。 http://jsfiddle.net/ezhsLw16/10

1 个答案:

答案 0 :(得分:2)

emailListCopy中唯一留下的人是arr中的最后一个人时,while循环将永远继续。

您可以通过执行以下操作获得所需的结果:

  1. 随机播放阵列。这是一系列给予者。
  2. 将其复制到接收器阵列。
  3. 将接收器阵列偏移1。
  4. 使用zip组合2个阵列。
  5. 通过这样做,您不必检查接收器是否与给予者相同。

    _.mixin({
        ldSanta: function (arr) {
            if (arr.length < 2) {
                throw "Invalid input, must have at least 2 people";
            }
            var givers = _.shuffle(arr);
            var receivers = _.clone(givers);
            receivers.push(receivers.shift());
            var pairs = _.map(_.zip(givers, receivers), function(pair) {
                return { giver: pair[0], receiver: pair[1] };
            });
            return pairs;
        }
    });
    

    Live Demo(JSFiddle现在有点慢)