Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ember.js - extract distinct properties from array

lets say I have the following array, and this is used in my controller

songs = [
  {trackNumber: 4, title: 'Ob-La-Di, Ob-La-Da', genre: 'pop'},
  {trackNumber: 2, title: 'Back in the U.S.S.R.', genre: 'rock'},
  {trackNumber: 3, title: 'Glass Onion', genre: 'pop'},
];

I would like to have a property on my controller that returns an array of unique genres

eg

genres: function() {
  ...
}...

and in this case would return

['pop', 'rock']

is there some elegant way to do this with ember, using computed properties an or observers?

like image 241
kabal Avatar asked Nov 11 '13 23:11

kabal


1 Answers

My original answer is at the bottom, but the latest Ember releases provide a really nice new solution for this:

genres: Ember.computed.mapBy('songs', 'genre'),
uniqueGenres: Ember.computed.uniq('genres'),

References: mapBy and uniq. Computed property macros are great =)

previous answer:

genres: function() {
  return this.get('songs').map(function(song){
    return song.genre
  }).filter(function(genre, index, arr){
    return arr.indexOf(genre) == index // throw away any instances which are not first
  })
}.property('songs'),

note, I'm leveraging 'modern' array functions such as map and filter here, if you need to support older browsers, you'll need to shim those or write this another way. The filter I used for removing duplicates is the first that occurred to me, it's probably not very performant and if you've already loaded a library with a unique function (like underscore.uniq), you should use that.

Very little of this is Ember specific of course, the .property('songs') on the end is literally all you need to specify that this is a computed property, which will be cached and recomputed if songs changes (assumes Ember 1.0)

References: MDN for map and filter

like image 153
Frances McMullin Avatar answered Oct 19 '22 11:10

Frances McMullin