【问题标题】:Underscore.js - Map Array of key/value pairs to an Object - One linerUnderscore.js - 将键/值对数组映射到对象 - 一个衬里
【发布时间】:2013-07-22 01:08:42
【问题描述】:

我一直在经历underscore docs,但我似乎无法找到一种方法(或嵌套方法调用)来进行以下转换:

假设我有以下 Javascript 数组:

 [{ "name" : "sEcho", "value" : 1},{ "name" : "iColumns", "value" : 12}, ... ]

而且我需要把它转换成下面的对象:

 {
      sEcho: 1,
      iColumns: 12,
      ...
 }

我使用 underscore.js 是有原因的,所以它必须是一个单行。

【问题讨论】:

  • 一行? _.map(arr,function(v,o){o={};return o[v.name]=v.value,o });不确定是否有更短的方法...
  • @elclanrs 这将创建一个对象数组。你只想要一个对象。
  • @AaditMShah:对,我当时理解错了……

标签: javascript underscore.js


【解决方案1】:

Sza's answer 的变体,使用 _.object 的“对数组”签名:

_.object(_.map(data, function(x){return [x.name, x.value]}))

【讨论】:

  • 不错!如果您使用打字稿,甚至可以节省一些击键;)_.object(_.map(data, (x) => {return [x.name, x.value]}))
  • @parliament 或 coffeescript :-)
  • 此外,Sza 的示例在没有 zip 的情况下也可以工作(因为 object 采用单个名称/val 对数组或两个不同的数组)。所以你可以做_.object(_pluck(data, 'name'), _.pluck(data, 'value'))
  • 说到其他语言,最清楚的可能是使用 CS 中的理解:_.object([o.name, o.value] for o in data)
  • 使用_.chain 函数可能更清楚:gist.github.com/ablanchet/f8b9c3ece0812ebf3f3c
【解决方案2】:

由于没有人将此作为答案发布,因此我发布它是因为我认为它比 Jan's answer 更好。没有内联函数,它更短,更干净。

_.object(_.pluck(data, 'name'), _.pluck(data, 'value'));

【讨论】:

  • AFAICS 下划线不明确保证pluckmap 结果的任何顺序,所以即使这在当前浏览器中有效,我也不会依赖它。想象一下,要找出一个值被分配给错误键的错误是多么困难。
  • 你说的是真的,但是我会注意到 OP 没有明确要求相同的订单。
  • 我不担心映射中键值对的顺序(AFAIK,现在无论如何在 JS 中都可以保证),而是将值分配给错误的键。有时,在某些浏览器中,提取名称可能会返回另一个顺序而不是提取值,这会完全弄乱您的数据并返回例如{sEcho:12, iColumns:1} 而不是预期的结果。这就是为什么我更愿意在 reducemap 之类的单个操作中进行键值映射
  • @peterp 我明白了。但在这种情况下,pluckmapobject 函数都在数组上运行,其中的顺序是有保证的,所以没有问题。
  • 同意,underscore.js 的当前实现在这方面是安全的;但在没有明确保证的情况下,未来版本的实现可能会有所不同。我对“某些浏览器”绝对是错误的,它需要“其他版本的 underscore.js”来破坏代码,感谢您的提醒。随意称我为偏执狂,但我仍然不想依赖命令。 :)
【解决方案3】:

应该这样做:

_.reduce(array, function(o, v){
    o[v.name] = v.value;
    return o;
}, {});

作为一个单行者(你在开玩笑吧?):

_.reduce(array,function(a,b){a[b.name]=b.value;return a},{});

【讨论】:

  • 为什么要对b.value 值求和?为什么不是简单的a[b.name] = b.value
  • @muistooshort 我以为它应该总结它们,不知道为什么 xD
  • 我没有看到任何求和请求。如果他们试图用单行符变得聪明(还有什么其他原因?),那么你不妨公然表达你对维护者的仇恨并添加一个逗号运算符:_(a).reduce(function(m, h) { return m[h.name] = h.value, m }, { })。呵呵。
  • @muistooshort:我一定会发表评论 8-)
  • 这个答案是性能最高的,因为它只需要遍历原始数组。
【解决方案4】:
var names = _.pluck(data, 'name');
var values = _.pluck(data, 'value');
var result = _.object(_.zip(names, values));
console.log(result);

【讨论】:

  • +1 虽然有趣的是需要 3 种单独的鲜为人知的专用方法来用相同数量的代码来做某事,就像使用 1 种相对知名的方法(减少)。
【解决方案5】:

假设您有以下 JavaScript 数组:

var list = [
    {
         name: "sEcho",
         value: 1
    },
    {
         name: "iColumns",
         value: 12
    },
    ...
];

您可以将其转换为您想要的格式,如下所示:

var table = _.reduce(list, function (table, item) {
    table[item.name] = item.value;
    return table;
}, {});

这不是单排,但我认为您的字面意思不是单排。有吗?

如果您真的是指单排,这里是单排:

var t = _.reduce(list, function (t, i) { return t[i.name] = i.value, t; }, {});

是的,其他人也提供了相同的答案。不过那只是因为你的问题的答案很简单。

【讨论】:

    【解决方案6】:
    var a =  [{ "name" : "sEcho", "value" : 1},{ "name" : "iColumns", "value" : 12} ];
    
    var o = {}; _.each(a, function(e) { o[e.name] = e.value; });
    
    console.log(o);
    // Object {sEcho: 1, iColumns: 12} 
    

    【讨论】:

      【解决方案7】:

      我认为使用 reduce 的完美场所:

      _.reduce(ary, function(memo, obj){ memo[obj["name"]] = obj["value"]; return memo }, {});

      【讨论】:

        【解决方案8】:
        var arr = [{ "name" : "sEcho", "value" : 1},{ "name" : "iColumns", "value" : 12}]
        

        ES6

        _.mapObject( _.indexBy(arr, 'name'), (v) => v.value )
        

        ES5

        _.mapObject( _.indexBy(arr, 'name'), function (v) { return v.value; } )
        

        这会迭代两次

        【讨论】:

          猜你喜欢
          • 2023-02-05
          • 1970-01-01
          • 2019-04-28
          • 1970-01-01
          • 2012-01-11
          • 1970-01-01
          • 2018-03-10
          • 2020-07-22
          • 1970-01-01
          相关资源
          最近更新 更多