Chin
Chin

Reputation: 12712

finding by object key in underscore.js

I have the following object

{ join: {} }

I'd like to find it's default object from the array below

[
    { login: { label: 'Login', url: '#login' } },
    { join: { label: 'Join', url: '#join', theme: 'a' } },
    { home: { label: 'none', icon: 'home', url: '#', theme: 'a' } }
]

I'd like to loop through the array and match the key, in this case 'join'.

This is what I have so far:

 var butt_to_find = { join: {} }
 var all_buttons = 'array above'
 var matching = _.find(all_buttons, function(default_button){
 return if default_butt key @ 1 is the same as butt_to_find key @ 1;
  });

This is the first time I've used underscore after hearing so much about it. Any help, more than welcome

Upvotes: 11

Views: 45789

Answers (3)

Shanimal
Shanimal

Reputation: 11718

var def = {join: {}}
var defs = [
    { login: { label: 'Login', url: '#login' } },
    { join: { label: 'Join', url: '#join', theme: 'a' } },
    { home: { label: 'none', icon: 'home', url: '#', theme: 'a' } }
]
_.find(defs,function(item,key){
    return _.has(item,_.keys(def)[0])
})

You can also switch to the lodash library (a drop in version of underscore) and do this

_.compact(_.pluck(defs,_.keys(def)[0]))

Upvotes: 1

davidchambers
davidchambers

Reputation: 24806

var buttons = [
  { login: { label: 'Login', url: '#login' } },
  { join: { label: 'Join', url: '#join', theme: 'a' } },
  { home: { label: 'none', icon: 'home', url: '#', theme: 'a' } }
]

_.find(buttons, function (button) { return 'join' in button })

The problem is that you're using a suboptimal data structure. This would make more sense, and produce simpler code:

var buttons = {
  login: {label: 'Login', url: '#login'},
  join: {label: 'Join', url: '#join', theme: 'a'},
  home: {label: 'none', icon: 'home', url: '#', theme: 'a'}
}

buttons.join // equivalent to the `_.find` line in the first example (but much simpler)

Perhaps you're using an array because the order of the buttons is important. In this case, I'd use an array of arrays:

var buttons = [
  ['login', {label: 'Login', url: '#login'}],
  ['join', {label: 'Join', url: '#join', theme: 'a'}],
  ['home', {label: 'none', icon: 'home', url: '#', theme: 'a'}]
]

_.find(buttons, function (button) { return button[0] === 'join' })

Upvotes: 20

ruakh
ruakh

Reputation: 183270

var matching =
( _.find
  ( all_buttons,
    function (button)
    { return _.keys(butt_to_find)[0] in button;
    }
  )
);

where _.keys(butt_to_find) evaluates to ['join'] (an array containing the keys of butt_to_find), _.keys(butt_to_find)[0] evaluates to 'join' (the first element of said array), and _.keys(butt_to_find)[0] in button evaluates to either true or false, depending whether button contains 'join' as a key. (The in operator is a regular JavaScript operator, not something added by underscore.js.)

Upvotes: 4

Related Questions