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

时间:2022-07-04 17:31:44

If I have an array of strings, I can use the .join() method to get a single string, with each element separated by commas, like so:

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

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

I have an array of objects, and I’d like to perform a similar operation on a value held within it; so from

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

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

perform the join method only on the name attribute, to achieve the same output as before.

只在name属性上执行join方法,以实现与以前相同的输出。

Currently I have the following function:

目前我有以下功能:

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

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

  return out.join(", ");
}

There’s nothing wrong with that code, it works, but all of a sudden I’ve gone from a simple, succinct line of code to a very imperative function. Is there a more succinct, ideally more functional way of writing this?

这段代码没有任何问题,它可以工作,但是突然之间,我从一个简单、简洁的代码行变成了一个非常必要的函数。是否有一种更简洁、更理想、更实用的写作方式?

7 个解决方案

#1


311  

If you want to map objects to something (in this case a property). I think Array.prototype.map is what you're looking for if you want to code functionally.

如果要将对象映射到某个对象(在本例中是属性)。我认为Array.prototype。如果你想在功能上编码,地图就是你要找的东西。

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

In modern JavaScript:

在现代JavaScript:

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

(fiddle)

(小提琴)

If you want to support older browsers, that are not ES5 complaint you can shim it (there is a polyfill on the MDN page above). Another alternative would be to use underscorejs's pluck method:

如果您想支持旧的浏览器,那不是ES5的抱怨,您可以对它进行shim(在上面的MDN页面上有一个polyfill)。另一种选择是使用underscorejs的采集方法:

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

#2


60  

Well you can always override the toString method of your objects:

你可以重写对象的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"

#3


8  

I don't know if there's an easier way to do it without using an external library, but I personally love underscore.js which has tons of utilities for dealing with arrays, collections etc.

我不知道在不使用外部库的情况下是否有更简单的方法,但我个人喜欢下划线。js具有大量处理数组、集合等的实用工具。

With underscore you could do this easily with one line of code:

有了下划线,你可以很容易地用一行代码做到这一点:

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

_。拔(arr的名字”)。加入(" ")

#4


8  

I've also come across using the reduce method, this is what it looks like:

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

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

The (a.name || a) is so the first element is treated correctly, but the rest (where a is a string, and so a.name is undefined) isn't treated as an object.

(a.name || a)因此第一个元素得到了正确的处理,但是其余的元素(a是字符串,所以a.name是未定义的)没有被当作对象来处理。

Edit: I've now refactored it further to this:

编辑:我现在已经重构到这个:

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

which I believe is cleaner as a is always a string, b is always an object (due to the use of the optional initialValue parameter in reduce)

我认为它更简洁,因为a始终是字符串,b始终是对象(由于在reduce中使用了可选的initialValue参数)

Edit 6 months later: Oh what was I thinking. "cleaner". I've angered the code Gods.

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

#5


2  

lets say the objects array is referenced by the variable users

假设对象数组被变量用户引用

If ES6 can be used then the easiest solution will be:

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

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

If not, and lodash can be used so :

如果不是,可以使用lodash:

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

#6


0  

On node or ES6:

在节点或ES6:

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

用户。地图(u = > u.name). join(" ")

#7


-1  

try this

试试这个

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"

#1


311  

If you want to map objects to something (in this case a property). I think Array.prototype.map is what you're looking for if you want to code functionally.

如果要将对象映射到某个对象(在本例中是属性)。我认为Array.prototype。如果你想在功能上编码,地图就是你要找的东西。

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

In modern JavaScript:

在现代JavaScript:

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

(fiddle)

(小提琴)

If you want to support older browsers, that are not ES5 complaint you can shim it (there is a polyfill on the MDN page above). Another alternative would be to use underscorejs's pluck method:

如果您想支持旧的浏览器,那不是ES5的抱怨,您可以对它进行shim(在上面的MDN页面上有一个polyfill)。另一种选择是使用underscorejs的采集方法:

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

#2


60  

Well you can always override the toString method of your objects:

你可以重写对象的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"

#3


8  

I don't know if there's an easier way to do it without using an external library, but I personally love underscore.js which has tons of utilities for dealing with arrays, collections etc.

我不知道在不使用外部库的情况下是否有更简单的方法,但我个人喜欢下划线。js具有大量处理数组、集合等的实用工具。

With underscore you could do this easily with one line of code:

有了下划线,你可以很容易地用一行代码做到这一点:

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

_。拔(arr的名字”)。加入(" ")

#4


8  

I've also come across using the reduce method, this is what it looks like:

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

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

The (a.name || a) is so the first element is treated correctly, but the rest (where a is a string, and so a.name is undefined) isn't treated as an object.

(a.name || a)因此第一个元素得到了正确的处理,但是其余的元素(a是字符串,所以a.name是未定义的)没有被当作对象来处理。

Edit: I've now refactored it further to this:

编辑:我现在已经重构到这个:

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

which I believe is cleaner as a is always a string, b is always an object (due to the use of the optional initialValue parameter in reduce)

我认为它更简洁,因为a始终是字符串,b始终是对象(由于在reduce中使用了可选的initialValue参数)

Edit 6 months later: Oh what was I thinking. "cleaner". I've angered the code Gods.

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

#5


2  

lets say the objects array is referenced by the variable users

假设对象数组被变量用户引用

If ES6 can be used then the easiest solution will be:

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

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

If not, and lodash can be used so :

如果不是,可以使用lodash:

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

#6


0  

On node or ES6:

在节点或ES6:

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

用户。地图(u = > u.name). join(" ")

#7


-1  

try this

试试这个

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"