Join the Stack Overflow Community
Stack Overflow is a community of 6.5 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I have array of objects that looks like this

var array=[
{id:123, value:"value1", name:"Name1"},
{id:124, value:"value2", name:"Name1"},
{id:125, value:"value3", name:"Name2"}
{id:126, value:"value4", name:"Name2"}
...
]

As you can see some names are repeated. I want to get new array with names only, but if some name repeats don't want to add it again, I want this array

var newArray = ["Name1", "Name2"]

I'm trying to this with map

var newArray = array.map((a)=>{
return a.name;
}); 

but the problem is that this returns

newArray = ["Name1", "Name1", "Name2", "Name2"]

How can I set some condition inside map, so it won't return element that already exist? I want to do this with maps or some other ES5 or ES6 feature.

share|improve this question
2  
Then remove the duplicates from the array. – Tushar 13 hours ago
2  
    
possible duplicate of Remove Duplicates from JavaScript Array – Bergi 8 hours ago
up vote 30 down vote accepted

With ES6, you could use Set for unique values, after mapping only the names of the objects.

This proposal uses a spread syntax ... for collecting the items in a new array.

const array = [{ id: 123, value: "value1", name:"Name1" }, { id: 124, value: "value2", name: "Name1" }, { id: 125, value: "value3", name: "Name2" }, { id: 126, value: "value4", name: "Name2" }],
      names = [...new Set(array.map(a => a.name))];

console.log(names);

share|improve this answer
3  
For my info.. what does ... do? – Rajshekar Reddy 13 hours ago
1  
@RajshekarReddy, it's a spread syntax ... for building an array with an iterable object. – Nina Scholz 13 hours ago
2  
Got my vote for the ... syntax :) – Dekel 13 hours ago
3  
I'm not upvoting for the "Set" itself, but rather for the clever use of the spread operator. It's always nice to learn something new or to see something new applied to a practical example, so this post deserves an upvote. – briosheje 13 hours ago
1  
@NinaScholz nice to learn new things... you got my vote.. :) – Rajshekar Reddy 13 hours ago

If you are looking for a javascript solution that is not ES6 (no Set) you can use the Array's reduce method:

var array=[
  {id:123, value:"value1", name:"Name1"},
  {id:124, value:"value2", name:"Name1"},
  {id:125, value:"value3", name:"Name2"},
  {id:126, value:"value4", name:"Name2"}
];
var names = array.reduce(function (a, b) {
  if (a.indexOf(b.name) == -1) {
    a.push(b.name)
  }
  return a;
}, []);

console.log(names);

share|improve this answer
1  
This answer also has the benefit that it doesn't require intermediate arrays or sets, especially ones containing only the names themselves. (It goes directly from array of objects to array of objects.) +1 – jpmc26 7 hours ago
    
@jpmc26 you are right. And thanks for the vote :) – Dekel 7 hours ago
    
@jpmc26 - sure it does (the second param in reduce).. but +1 – I wrestled a bear once. 6 hours ago
    
@Iwrestledabearonce, isn't this second param the same object as the returned one? – Kaiido 4 hours ago
    
Yea but it doesnt go straight from one to the other like sort or filter, its rebuilt from an empty array. – I wrestled a bear once. 4 hours ago

personally i don't see why everyone is getting all fancy with es6. if it were my code i'd prefer to support as many browsers as possible.

var array=[
{id:123, value:"value1", name:"Name1"},
{id:124, value:"value2", name:"Name1"},
{id:125, value:"value3", name:"Name2"},
{id:126, value:"value4", name:"Name2"}
];

var a = (function(a){
  for (var i = array.length; i--;)
    if (a.indexOf(array[i].name) < 0) a.push(array[i].name);
  return a;
})([]);

console.log(a);

share|improve this answer
    
Won't it be more performant to use an object as a dictionary instead of indexOf-ing all the time? E.g. do added[name] = true and if(added[name]) instead of if(a.indexOf(name)). – Bojidar Marinov 10 hours ago
    
@BojidarMarinov depends on the number of items, really – Eric Lagergren 9 hours ago
    
"personally i don't see why everyone is getting all fancy with es6" why are you courting a goto fail, leaking your index variable into the enclosing scope, etc. etc. ES6 was codified into the standard for good reasons, and is for the most part trivially easy to polyfill/transform for older browsers. – Jared Smith 2 hours ago
    
If leaking this and that is really an issue its even easier to put it ina closure but at that point you might as well use a polyfill.. its 2016 most people writing javascript are probably not writing enterprise level software – I wrestled a bear once. 1 hour ago

You can combine array#map() and array#filter():

var array = [{id:123, value:"value1", name:"Name1"}, {id:124, value:"value2", name:"Name1"}, {id:125, value:"value3", name:"Name2"}, {id:126, value:"value4", name:"Name2"}],
    names = array.map(i => i.name).filter((i, p, arr) => arr.indexOf(i) === p);

console.log(names);

share|improve this answer

You could also simply combine map with filter

var array = [
  {id:123, value:"value1", name:"Name1"},
  {id:124, value:"value2", name:"Name1"},
  {id:125, value:"value3", name:"Name2"},
  {id:126, value:"value4", name:"Name2"}
];

var unique = array
  .map( item => item.name )
  .filter( ( item, idx, arr ) => arr.indexOf( item ) == idx ) 

console.log(unique)

share|improve this answer

Many good answers here. I just would like to contribute with some diversity with hopes to give you another perspective.

Arrays are object type in JS so they can be used as a hash at the same time. By utilizing this functionality we can greatly simplify the job to be done in a single reduce operation with O(n) time complexity. If you are not happy with your array holding some properties other than the array keys you might consider keeping a separate hash object as well.

var array = [{id:123, value:"value1", name:"Name1"},
             {id:124, value:"value2", name:"Name1"},
             {id:125, value:"value3", name:"Name2"},
             {id:126, value:"value4", name:"Name2"}
            ],
   result = array.reduce((p,c) => p[c.name] ? p : (p[c.name] = true, p.push(c.name),p),[]);
console.log(result);

share|improve this answer

With ES6 this should do the job.

var array=[
    {id:123, value:"value1", name:"Name1"},
    {id:124, value:"value2", name:"Name1"},
    {id:125, value:"value3", name:"Name2"},
    {id:126, value:"value4", name:"Name2"}
];

var set = new Set();

array.map((a)=>{
    set.add(a.name);
}); 

console.log(set);

share|improve this answer
    
map is supposed to be used with pure functions, not to have side effects. This would be a job for forEach or reduce. – Vincent van der Weele 8 hours ago

Try this:

nArr = [];
array.filter((a)=>{
    if (nArr.indexOf(a.name) < 0) { 
        nArr.push(a.name); 
        return true 
    } else { 
        return false 
    }
}); 
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.