首页 文章

对对象数组中的值执行.join

提问于
浏览
185

如果我有一个字符串数组,我可以使用 .join() 方法获取单个字符串,每个元素用逗号分隔,如下所示:

["Joe", "Kevin", "Peter"].join(", ") // => "Joe, Kevin, Peter"

我有一个对象数组,我想对其中的值执行类似的操作;所以

[
  {name: "Joe", age: 22},
  {name: "Kevin", age: 24},
  {name: "Peter", age: 21}
]

仅对 name 属性执行 join 方法,以实现与以前相同的输出 .

目前我有以下功能:

function joinObj(a, attr){
  var out = [];

  for (var i = 0; i < a.length; i++){
    out.push(a[i][attr]);
  }

  return out.join(", ");
}

这段代码没有任何问题,它可以工作,但突然之间,我已经从一个简单,简洁的代码行转变为一个非常重要的代码 . 是否有更简洁,更理想的写作方式?

8 回答

  • 8

    我不是在不使用外部库的情况下更轻松地做到这一点,但我个人喜欢underscore.js,它有大量用于处理数组,集合等的实用工具 .

    使用下划线,您可以使用一行代码轻松完成此操作:

    _.pluck(arr, 'name').join(', ')

  • 0

    让我们说对象数组由变量 users 引用

    如果可以使用ES6,那么最简单的解决方案是:

    users.map(user => user.name).join(', ');
    

    如果没有,可以使用lodash

    _.map(users, function(user) {
         return user.name;
     }).join(', ');
    
  • 2

    在节点或ES6上:

    users.map(u => u.name).join(', ')

  • 63

    如果要将对象映射到某个东西(在本例中为属性) . 我认为Array.prototype.map是你想要的功能代码 .

    [
      {name: "Joe", age: 22},
      {name: "Kevin", age: 24},
      {name: "Peter", age: 21}
    ].map(function(elem){
        return elem.name;
    }).join(",");
    

    在现代JavaScript中:

    [
      {name: "Joe", age: 22},
      {name: "Kevin", age: 24},
      {name: "Peter", age: 21}
    ].map(e => e.name).join(",");
    

    (fiddle)

    如果你想支持旧的浏览器,那么你可以使用它来填充它(在上面的MDN页面上有一个polyfill) . 另一种选择是使用underscorejs的pluck方法:

    var users = [
          {name: "Joe", age: 22},
          {name: "Kevin", age: 24},
          {name: "Peter", age: 21}
        ];
    var result = _.pluck(users,'name').join(",")
    
  • 9

    那么你总是可以覆盖对象的 toString 方法:

    var arr = [
        {name: "Joe", age: 22, toString: function(){return this.name;}},
        {name: "Kevin", age: 24, toString: function(){return this.name;}},
        {name: "Peter", age: 21, toString: function(){return this.name;}}
    ];
    
    var result = arr.join(", ");
    //result = "Joe, Kevin, Peter"
    
  • 351

    我也遇到过使用 reduce 方法,这就是它的样子:

    [
      {name: "Joe", age: 22},
      {name: "Kevin", age: 24},
      {name: "Peter", age: 21}
    ].reduce(function (a, b) {return (a.name || a) + ", " + b.name})
    

    (a.name || a) 是第一个元素被正确处理,但其余的(其中 a 是一个字符串,所以 a.name 未定义)不被视为对象 .

    编辑:我现在已经进一步重构了这个:

    x.reduce(function(a, b) {return a + ["", ", "][+!!a.length] + b.name;}, "");
    

    我认为更清洁,因为 a 始终是一个字符串, b 始终是一个对象(由于在 reduce 中使用了optional initialValue parameter

    编辑6个月后:哦,我在想什么 . “清洁器” . 我激怒了代码众神 .

  • 0

    我知道的一个老线程,但仍然与遇到这个的任何人都非常相关 .

    这里建议使用Array.map,这是我一直使用的一个很棒的方法 . 还提到了Array.reduce ......

    我个人会在这个用例中使用Array.reduce . 为什么?尽管代码略微不那么干净/清晰 . 它比将map函数管道连接更有效 .

    原因是因为Array.map必须遍历每个元素以返回一个新数组,其中包含数组中对象的所有名称 . 然后,Array.join遍历数组的内容以执行连接 .

    您可以通过使用模板文字将代码转换为单行来提高jackweirdys的可读性 . “在所有现代浏览器中也支持”

    // a one line answer to this question using modern JavaScript
    x.reduce((a, b) => `${a.name || a}, ${b.name}`);
    
  • -1

    试试这个

    var x= [
      {name: "Joe", age: 22},
      {name: "Kevin", age: 24},
      {name: "Peter", age: 21}
    ]
    
    function joinObj(a, attr) {
      var out = []; 
      for (var i=0; i<a.length; i++) {  
        out.push(a[i][attr]); 
      } 
     return out.join(", ");
    }
    
    var z = joinObj(x,'name');
    z > "Joe, Kevin, Peter"
    var y = joinObj(x,'age');
    y > "22, 24, 21"
    

相关问题