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(",");
(小提琴)
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(",");
(小提琴)
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"