迭代对象属性并修改它们

时间:2014-09-24 09:51:07

标签: javascript underscore.js

Underscore.js在集合上提供_.each_.map,这很好,但我需要迭代我的对象的所有属性。我需要修改值并保留键。例如。我有类似的东西:{a:1, b:2, c:3}我需要执行一个更改值但保留键的操作。比方说,我会计算平方,我应该得到{a:1, b:4, c:9}。问题是:如何使用下划线(对vanilla javascript不感兴趣)?我喜欢这样的方法:

var a = {a:1, b:2, c:3}
_.magic(a, function(item){ return item*item; });

此外,如果可以链接它会很棒,因为我正在做一个地图,转储结果来执行每个,然后再次使用地图(因为我需要)。

4 个答案:

答案 0 :(得分:37)

_.mapObjectadded in version 1.8)正是您正在寻找的。


对于以前的版本,可以使用_.each回调的第三个参数来改变原始对象。

_.each({a:1, b:2, c:3}, function(value, key, obj) { obj[key] = value * value; });

_.reduce与初始备忘录一起使用也可以创建一个全新的对象。

_.reduce({a:1, b:2, c:3}, function(memo, value, key) {
    memo[key] = value * value;
    return memo;
}, {});

我更喜欢_.reduce方法。简单的mixin将使其行为与_.map完全相同。

_.mixin({
    magic: function(obj, iterator, context) {
        return _.reduce(obj, function(memo, value, key) {
            memo[key] = iterator.call(context, value, key, obj);
            return memo;
        }, {});
    }
});

答案 1 :(得分:17)

我在一些片段中看了一下,看看是否有一个选项来改变原始对象,但我没有找到任何有趣的内容,所以我选择了this:\ < / p>

var original = {a:1, b:2, c:3};
var squaredValues = _.object(_.map(original, function (value, key) {
    return [key, value * value];
}));

我希望有一个更优雅的解决方案。

答案 2 :(得分:4)

正如贾斯汀所说,_.mapObject 可能正是您所寻找的。 但是这会创建一个新对象(扩展{}),这可能不是您想要的(例如,如果它不是像new THREE.Vector3()这样的简单对象),请点击此处& #39;用不同的东西替换原始物体是没有用的。

对于这种情况(修改 in 给定对象中的值),只需使用_.each和iteratee函数的第三个参数:

_.each(complexObject, function(value, key, obj) {
  obj[key] = value * value;
}); 

答案 3 :(得分:1)

非常感谢Javier92指出了正确的解决方案。

无论如何,我不喜欢使用另一个使用另外两个下划线方法的下划线方法(它的可读性不大),所以我想出了一个简单的包装函数,它被混合到下划线中:

// mixin to make our new function available via _
_.mixin({
    updateAttributes: function(object, iteratee) {
        return _.object(_.map(object, function (value, key) {
            return [key, iteratee(value)];
        }));
    }
});

在代码中的某处使用它:

_.updateAttributes({a:1, b:2, c:3}, function(item){ return item*item; })
// Object {a: 1, b: 4, c: 9}

无法想到一个单字函数(可能有比updateAttributes更好的东西。)