如果我有一个字符串数组,我可以使用.join()
方法获取单个字符串,每个元素用逗号分隔,如下所示:
["Joe", "Kevin", "Peter"].join(", ") // => "Joe, Kevin, Peter"
我有一个对象数组,我想对其中的值执行类似的操作;所以来自
[
{name: "Joe", age: 22},
{name: "Kevin", age: 24},
{name: "Peter", age: 21}
]
仅对join
属性执行name
方法,以实现与之前相同的输出。
目前我有以下功能:
function joinObj(a, attr){
var out = [];
for (var i = 0; i < a.length; i++){
out.push(a[i][attr]);
}
return out.join(", ");
}
该代码没有任何问题,它可以工作,但突然之间,我已经从一个简单,简洁的代码行转变为一个非常重要的代码。有没有更简洁,更理想的写作方式呢?
答案 0 :(得分:403)
如果要将对象映射到某个东西(在本例中为属性)。我想如果你想要在功能上进行编码,Array.prototype.map
就是你要找的。 p>
[
{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(",");
如果您想支持不是ES5 compliant的旧浏览器,您可以对其进行填充(上面的MDN页面上有一个polyfill)。另一种选择是使用underscorejs的pluck
方法:
var users = [
{name: "Joe", age: 22},
{name: "Kevin", age: 24},
{name: "Peter", age: 21}
];
var result = _.pluck(users,'name').join(",")
答案 1 :(得分:67)
您可以随时覆盖对象的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"
答案 2 :(得分:9)
我也遇到过使用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个月后编辑:哦,我在想什么。 “清洁器”。我激怒了代码众神。
答案 3 :(得分:8)
我不知道是否有一种更简单的方法可以在不使用外部库的情况下实现它,但我个人爱 underscore.js,它有大量的实用程序来处理数组,集合等
使用下划线,您可以使用一行代码轻松完成此操作:
_.pluck(arr, 'name').join(', ')
答案 4 :(得分:2)
在节点或ES6上:
users.map(u => u.name).join(', ')
答案 5 :(得分:2)
假设对象数组由变量users
如果可以使用ES6,那么最简单的解决方案是:
users.map(user => user.name).join(', ');
如果没有,可以使用lodash:
_.map(users, function(user) {
return user.name;
}).join(', ');
答案 6 :(得分:1)
如果对象和动态键:"applications\":{\"1\":\"Element1\",\"2\":\"Element2\"}
Object.keys(myObject).map(function (key, index) {
return myObject[key]
}).join(', ')
答案 7 :(得分: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}`);
答案 8 :(得分:0)
不确定,但是所有这些答案都可以正常工作,但不是最佳选择,因为它们执行两次扫描,您可以在一次扫描中执行。即使O(2n)被认为是O(n)总是比真正的O(n)好。
const Join = (arr, separator, prop) => {
let combined = '';
for (var i = 0; i < arr.length; i++) {
combined = `${combined}${arr[i][prop]}`;
if (i + 1 < arr.length)
combined = `${combined}${separator} `;
}
return combined;
}
这看起来像是旧学校,但是允许我做这样的事:
skuCombined = Join(option.SKUs, ',', 'SkuNum');
答案 9 :(得分:0)
您可以转换为数组以获取对象名称
var objs = [
{name: "Joe", age: 22},
{name: "Kevin", age: 24},
{name: "Peter", age: 21}
];
document.body.innerHTML = Object.values(objs).map(function(obj){
return obj.name;
});
答案 10 :(得分:0)
最简单的方法:
const oldArrayOfObjects = [
{name: "Bob", age:40},
{name: "Andrew", age:25},
{name: "Peter", age:30}];
const newArrayOfStringNames = oldArrayOfObjects.map((OA) => OA.name);
const newArrayOfAges = oldArrayOfObjects.map((OA) => OA.age);
console.log({newArrayOfStringNames, newArrayOfAges})
答案 11 :(得分:-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"