什么是_.pluck的等效对象

时间:2013-08-13 20:45:44

标签: javascript object underscore.js transformation

我已经重新实现了我自己需要的版本,但我怀疑它已经包含在下划线中,因为它非常简单并且与许多其他功能密切相关。但我想不出应该叫什么。

基本上,我想要的是_.pluck的一个版本,它使用对象并返回一个对象而不是一个数组(及其相关的键)。

所以,例如,如果我有一个像这样的对象:

elements: {
    steam: {
        temperature: 100,
        color: 'orange',
        state: 'gas'
    },
    water: {
        temperature: 50,
        color: 'blue',
        state: 'liquid'
    },
    ice: {
        temperature: 0,
        color: 'white',
        state: 'solid'
    }
}

我想打电话给_.something(elements, 'temperature')

让它返回

{
    steam: 100,
    water: 50,
    ice: 0
}

而不是_.pluck(elements, 'temperature')返回

[100, 50, 0]

这个转变叫做什么,它是否已经包含在下划线中?我自己用jQuery的每个循环编写了一个快速版本,因为我比jQuery更熟悉而不是下划线(包含在下面),但如果可能的话,我更愿意使用库中的一个。

$.objPluck = function(obj, key) {
    var ret = {};
    $.each(obj, function(k, value) {
        ret[k] = value[key];
    });
    return ret;
}

6 个答案:

答案 0 :(得分:9)

没有办法在下划线 1.4.4 中做到这一点,但是如果你想留在下划线,你可以做到

_.object(_.keys(elements), _.pluck(elements, 'temperature'))

Demo at jsfiddlebfavaretto

提供

截至下划线 1.8.3 ,可以使用_.mapObject(elements, 'temperature');简洁地完成此操作。

Updated demo

答案 1 :(得分:5)

值得在这里添加使用ES6箭头功能等的解决方案:

Object.keys(elements).map(f=>elements[f].temperature)

请注意,这不适用于较旧的javascript引擎,但在带有--harmony的node.js 0.12中,它可以很好地工作,或者使用node.js 4.x及更高版本。我刚刚在Chrome 46中对此进行了测试,它运行正常。

它的优点是不需要任何额外的库,如下划线或lodash,但当然只适用于新的JS引擎。

答案 2 :(得分:3)

在lodash(类似于下划线)上,您可以使用_.mapValues(elements,'temperature') 它返回{steam: 100, water: 50, ice: 0}

lodash ref:_.mapValues

顺便说一句,您可以使用_.mapKeys在一行中构建对象哈希 _.mapKeys(elements,'color') //{orange: Object, blue: Object, white: Object}

答案 3 :(得分:1)

你不需要像第三方这样容易的东西

// with a plain old for loop
const temps = {}
for (let key in data["elements"]) {
    dikt[key] = temps["elements"][key]["temperature"]
}
return temps

// with a reduce

Object.keys(data['elements']).reduce((acc, key) => acc[key] = data['elements'][key]['temperature'] , temps)

答案 4 :(得分:0)

您可以使用JavaScript for-in loop来迭代对象的键:

var list = [];

// Iterate through each object key, and pick wanted the values.
for(var name in obj)
{
    if (obj.hasOwnProperty(name) && name === "temperature")
    {
       list.push(obj[name]);
    }
}

以上是一个简化示例,但您应该能够轻松修改以将其封装在更通用的函数中。此外,您不需要在这里使用JQuery - 本机JavaScript实现会更快。

JSLint建议obj.hasOwnProperty(name)检查。

答案 5 :(得分:0)

在较新的版本中,实际上有一个内置函数来执行此操作。

如果您将字符串而不是函数提供给mapObject,它会将其解释为属性名称并表现为" pluckObject"。他们所接受的大多数功能都令人惊讶地自由。

> _.mapObject(elements,'temperature')
Object {steam: 100, water: 50, ice: 0}

如果您想要一个明确的功能,您可以查看_.pluck implemented的方式并编写您自己的类似版本:

_.mixin({
  pluckObject: function(obj, key) {
    return _.mapObject(obj, _.property(key));
  }
});

这有点多余,但它会让你的意图更清晰。