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:
["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.
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?
This question is related to
javascript
arrays
object
An old thread I know but still super relevant to anyone coming across this.
Array.map has been suggested here which is an awesome method that I use all the time. Array.reduce was also mentioned...
I would personally use an Array.reduce for this use case. Why? Despite the code being slightly less clean/clear. It is a much more efficient than piping the map function to a join.
The reason for this is because Array.map has to loop over each element to return a new array with all of the names of the object in the array. Array.join then loops over the contents of array to perform the join.
You can improve the readability of jackweirdys reduce answer by using template literals to get the code on to a single line. "Supported in all modern browsers too"
// a one line answer to this question using modern JavaScript
x.reduce((a, b) => `${a.name || a}, ${b.name}`);
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.
With underscore you could do this easily with one line of code:
_.pluck(arr, 'name').join(', ')
On node or ES6+:
users.map(u => u.name).join(', ')
you can convert to array so get object name
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;
});
_x000D_
not sure, but all this answers tho they work but are not optiomal since the are performing two scans and you can perform this in a single scan. Even though O(2n) is considered O(n) is always better to have a true 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;
}
This might look like old school, but allows me to do thig like this:
skuCombined = Join(option.SKUs, ',', 'SkuNum');
Well you can always override the toString
method of your objects:
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"
If object and dynamical keys: "applications\":{\"1\":\"Element1\",\"2\":\"Element2\"}
Object.keys(myObject).map(function (key, index) {
return myObject[key]
}).join(', ')
I've also come across using the reduce
method, this is what it looks like:
[
{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.
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
)
Edit 6 months later: Oh what was I thinking. "cleaner". I've angered the code Gods.
lets say the objects array is referenced by the variable users
If ES6 can be used then the easiest solution will be:
users.map(user => user.name).join(', ');
If not, and lodash can be used so :
_.map(users, function(user) {
return user.name;
}).join(', ');
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"
Source: Stackoverflow.com