下划线根据对象键创建数组

时间:2014-03-07 09:42:19

标签: javascript underscore.js

假设我有一个像这样的js对象

{
    a: 5,
    b: 1,
    c: 3
}

使用Underscore我想要做的是生成一个类似于以下内容的数组;

["a","a","a","a","a","b","c","c","c"]

我可以通过以下代码实现我想要的目标

var i = {
    a: 5,
    b: 1,
    c: 3
};

unpack = function (i, item) {
    var items = [];
    _.range(0, i).forEach(function (i) {
        items.push(item)
    })
    return items;
}

console.log(_.flatten(_.map(i, unpack)));

http://jsfiddle.net/VCFZx/但它似乎不是最干净的方式吗?

2 个答案:

答案 0 :(得分:2)

在ECMA5中你可以这样做

的Javascript

function createFilledArray(obj) {
    return Object.keys(obj).reduce(function(acc, key) {
        var repeat = obj[key],
            count;

        for(count = 0; count < repeat; count += 1) {
            acc.push(key);
        }

        return acc;
    }, []);
}

var a = {
    'a': 5,
    'b': 1,
    'c': 3
};

console.log(createFilledArray(a));

jsFiddle

underscore方面看起来像这样

的Javascript

function createFilledArray(obj) {
    return _.reduce(_.keys(obj), function(acc, key) {
        var repeat = obj[key],
            count;

        for(count = 0; count < repeat; count += 1) {
            acc.push(key);
        }

        return acc;
    }, []);
}

jsFiddle

如果您想更进一步并替换for

,那该怎么办?

的Javascript

function createFilledArray(obj) {
    return _.reduce(_.keys(obj), function(acc, key) {
        _.times(obj[key], function() {
            acc.push(key);
        });

        return acc;
    }, []);
}

jsFiddle

现在考虑一下兴趣因素,让我们看看上面3个函数的性能,因为我们介绍了更多的Underscores方法,我们也将它们与@mrhobo

的公认解决方案进行比较

以下是jsPerf

其他一些都没有考虑到这一点,而且从你的问题中不清楚,字母顺序是否是必须的。如果是,则需要将sort投入混合,因为这些都不能保证订购。

最后,在评论中提到的ES3中。

的Javascript

function createFilledArray(obj) {
    var acc = [],
        key,
        repeat,
        count;

    for (key in obj) {
        if (obj.hasOwnProperty(key)) {
            for (count = 0, repeat = obj[key]; count < repeat; count += 1) {
                acc.push(key);
            }
        }
    }

    return acc;
}

jsFiddle

我已经将ES3方法添加到jsPerf中。

如果你想用其他Underscore方法链接结果。

_.chain(createFilledArray(a)).forEach(function(element) {
    console.log(element);
});

答案 1 :(得分:2)

这个怎么样:

var obj = 
{
a :5,
b : 1,
c : 3
};

console.log( 
  _.flatten(_.map(_.keys(obj), function (key) {
      return _.times(obj[key], function() { return key; });  
  }))
);

http://jsfiddle.net/J6bqb/

请注意,此解决方案纯粹是功能性的。

这是一个很好的链接版本:

  _.chain(_.keys(obj))
    .map(function (key) {
      return _.times(obj[key], function() { return key; });  })
    .flatten()
    .value()