1
var arr = ["a", "a", "b", "b", "c", "d", "d"]

I'm looking for function that returns non-repeating element like "c" from the above example as that's the only one without duplicate.

I have searched for an hour but all the results I found online returns:

["a", "b", "c", "d"]

which is not what I want.

Example - how to push the single occurring Bond allBond to uniqueBond ?

const bondFilms = [
  { "title" : "Skyfall", "year" : 2012, "actor" : "Daniel Craig", "gross" : "$1,108,561,008" },
  { "title" : "Thunderball", "year" : 1965, "actor" : "Sean Connery", "gross" : "$1,014,941,117" },
  { "title" : "Goldfinger", "year" : 1964, "actor" : "Sean Connery", "gross" : "$912,257,512" },
  { "title" : "Live and Let Die", "year" : 1973, "actor" : "Roger Moore", "gross" : "$825,110,761" },
  { "title" : "You Only Live Twice", "year" : 1967, "actor" : "Sean Connery", "gross" : "$756,544,419" },
  { "title" : "The Spy Who Loved Me", "year" : 1977, "actor" : "Roger Moore", "gross" : "$692,713,752" },
  { "title" : "Casino Royale", "year" : 2006, "actor" : "Daniel Craig", "gross" : "$669,789,482" },
  { "title" : "Moonraker", "year" : 1979, "actor" : "Roger Moore", "gross" : "$655,872,400" },
  { "title" : "Diamonds Are Forever", "year" : 1971, "actor" : "Sean Connery", "gross" : "$648,514,469" },
  { "title" : "Quantum of Solace", "year" : 2008, "actor" : "Daniel Craig", "gross" : "$622,246,378" },
  { "title" : "From Russia with Love", "year" : 1963, "actor" : "Sean Connery", "gross" : "$576,277,964" },
  { "title" : "Die Another Day", "year" : 2002, "actor" : "Pierce Brosnan", "gross" : "$543,639,638" },
  { "title" : "Goldeneye", "year" : 1995, "actor" : "Pierce Brosnan", "gross" : "$529,548,711" },
  { "title" : "On Her Majesty's Secret Service", "year" : 1969, "actor" : "George Lazenby", "gross" : "$505,899,782" },
  { "title" : "The World is Not Enough", "year" : 1999, "actor" : "Pierce Brosnan", "gross" : "$491,617,153" },
  { "title" : "For Your Eyes Only", "year" : 1981, "actor" : "Roger Moore", "gross" : "$486,468,881" },
  { "title" : "Tomorrow Never Dies", "year" : 1997, "actor" : "Pierce Brosnan", "gross" : "$478,946,402" },
  { "title" : "The Man with the Golden Gun", "year" : 1974, "actor" : "Roger Moore", "gross" : "$448,249,281" },
  { "title" : "Dr. No", "year" : 1962, "actor" : "Sean Connery", "gross" : "$440,759,072" },
  { "title" : "Octopussy", "year" : 1983, "actor" : "Roger Moore", "gross" : "$426,244,352" },
  { "title" : "The Living Daylights", "year" : 1987, "actor" : "Timothy Dalton", "gross" : "$381,088,866" },
  { "title" : "A View to a Kill", "year" : 1985, "actor" : "Roger Moore", "gross" : "$321,172,633" },
  { "title" : "License to Kill", "year" : 1989, "actor" : "Timothy Dalton", "gross" : "$285,157,191" }
];

let uniqueBond = ""
let allBond = []
for (i = 0; i < bondFilms.length; i++) {
  allBond.push(bondFilms[i].actor)
}
console.log(allBond)

Get all unique values in a JavaScript array (remove duplicates) does not solve it as it only removes duplicates, but I want to keep uniques.

  • Since it is array of object, it is better if you write what is your criteria for uniqueness? Is it title or any values or all the values? – snnsnn Sep 13 '19 at 13:49
  • Please don't edit questions in a way that invalidates existing answers. – georg Sep 13 '19 at 13:51
  • Possible duplicate of [Get all unique values in a JavaScript array (remove duplicates)](https://stackoverflow.com/questions/1960473/get-all-unique-values-in-a-javascript-array-remove-duplicates) – mindmaster Sep 13 '19 at 14:02
  • @mindmaster Nope. I also posted dupes, he wants values that only occur once. Not a list of unique values – mplungjan Sep 13 '19 at 14:03
  • Thanks for all your answers guys. I don't quite understand how it works yet, but I've saved it and will get my JS lecturer to explain when I'm in class tomorrow. Also noted on the edit - didn't mean to invalidate any answers!! My apologies! –  Sep 13 '19 at 14:07

9 Answers9

4

You can use the fact that if an element occurs only once in the array, its indexOf and lastIndexOf will be the same. So

uniqueBond = bondFilms
     .map(film => film.actor)
     .filter((actor, _, actors) => actors.indexOf(actor) === actors.lastIndexOf(actor))

Applied to the abc example:

let arr = ["a", "a", "b", "b", "c", "d", "d"];

let uniq = arr.filter(x => arr.indexOf(x) === arr.lastIndexOf(x));

console.log(uniq);
georg
  • 211,518
  • 52
  • 313
  • 390
1

You can do it this way:

var arr = ["a", "a", "b", "b", "c", "d", "d"];

let count={};
arr.forEach(x=>{

 if(!count[x]) count[x]=0;
 count[x]++;

})

let result = arr.filter(x=>count[x]===1);
console.log(result)

Note since we store counts in object using array value as key and since keys in JS objects are strings, this code doesn't distinguish between 5 and "5". That is it will return [1, 2] from an input of say [1, 2, 5, "5"] because it will consider 5 and "5", "same". Other than that, it should be ok.

Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90
0

try this:

let uniqueBonds = [...new Set([...allBonds])];

Basically with Set you will get unique items and you convert them to array with Spread Operator.

niranjan_harpale
  • 2,048
  • 1
  • 17
  • 21
0

You can meet the requirement by filtering items that have the same first index and last index:

var arr = ["a", "a", "b", "b", "c", "d", "d"];
var uniq = arr.filter((item) => arr.indexOf(item) === arr.lastIndexOf(item));

console.log(uniq)
antonku
  • 7,377
  • 2
  • 15
  • 21
0

var arr = ["a", "a", "b", "b", "c", "d", "d"]

const newtest = arr.filter((element, index, array) => {
  const temp = array.filter(x => x === element);
  if(temp.length < 2) {
    return element;
  }
})

console.log('original ---  ', arr);
console.log('final ---  ', newtest);
RamKumar
  • 126
  • 1
  • 10
0

You can try something like this:

var arr = ["a", "a", "b", "b", "c", "d", "d"]

var counts = arr.reduce(function(acc, curr) { return Object.assign(acc, {[curr]: (acc[curr] || 0) + 1})   }, {})

var singleOccurrences = Object.keys(counts).filter(function(k) { return counts[k] === 1})

console.log(singleOccurrences);

Explanation:

var counts = arr.reduce(function(acc, curr) { return Object.assign(acc, {[curr]: (acc[curr] || 0) + 1}) }, {}) counts the occurrences for each item of the list (returning an object, whose keys are the items - for each key, the value is the count of the occurrences)

var singleOccurrences = Object.keys(counts).filter(function(k) { return counts[k] === 1}) iterates over keys in counts and apply a filter to the list, preserving only the kyes with exactly one occurrence

I hope this can help you!

Pietro Martinelli
  • 1,776
  • 14
  • 16
0

Use indexOf and compare it to lastIndexOf

var result = [1,1,2].filter( ( x, i, array ) => array.indexOf(x) === array.lastIndexOf(x))
console.log(result)
Sam Stephenson
  • 5,200
  • 5
  • 27
  • 44
0

I think using indexOf and lastIndexOf is the best solution. However if you for some unknown reason don't want to do that, here is my contribution with some es6 spread operators and reduce().

let a = ["1", "1", "2", "3", "3", "1"];

const uniqueItems = a.reduce((acc, item, i) => ![...a.slice(0,i), ...a.slice(i+1,a.length)].includes(item) 
  ? acc.concat([item]) 
  : acc , [])

console.log(uniqueItems);
// output: ['2']
Jonas Johansson
  • 417
  • 3
  • 8
0

You can try the following function to get unique values. It creates a hash for counting the frequency of every element in the arr and returns the unique values with frequency equals to 1

function getUnique(arr){
  var hash = {};
  var uniques = [];
  arr.forEach(ele =>{
    if(hash[ele]){
      hash[ele] +=1
    }
    else{
      hash[ele] = 1;
    }
  });
  
  Object.keys(hash).forEach(key =>{
    if(hash[key]==1){
      uniques.push(key);
    }
  });
 
 return uniques;
 
}
var arr = ["a", "a", "b", "b", "c", "d", "d"];
console.log(getUnique(arr));
Ankit
  • 604
  • 6
  • 13