2014-04-19 3 views
1

Première utilisation en soulignant et je suis coincé et ne peut pas trouver un exemple.underscorejs pluck tableau bidimensionnel

Mes données est:

[{ 
     "store_name": "Store 1", 
     "franchisee_id": "id01", 
     "dish_menu": "Breakfast", 
     "dish_count": "17" 
    }, { 
     "store_name": "Store 1", 
     "franchisee_id": "id01", 
     "dish_menu": "Light Meals", 
     "dish_count": "7" 
    }, { 
     "store_name": "Store 1", 
     "franchisee_id": "id01", 
     "dish_menu": "Sandwiches", 
     "dish_count": "12" 
    }, { 
     "store_name": "Store 2", 
     "franchisee_id": "id02", 
     "dish_menu": "Breakfast", 
     "dish_count": "7" 
    }, 
     ............ 
] 

J'ai réussi (avec un peu d'aide ici) pour tirer la store_name distincte avec la commande enchaînée suivante, puis placez-le dans une déclaration HTML Je construis:

var stores = _.chain(json).pluck("store_name").sort().uniq(true).value(); 
var tempHTML = ""; 

stores.forEach(function (entry) { 
    tempHTML = tempHTML + '<option value="' + entry + '">' + entry + '</option>'; 
}); 

Mais je suis en train de faire correspondre la franchisee_id à la store_name distincte et essentiellement construire mon code HTML comme ci-dessous:

stores.forEach(function (entry) { 
    tempHTML = tempHTML + '<option value="' + FRANCHISEE_ID + '">' + STORE_NAME + '</option>'; 
}); 

Y a-t-il un moyen de _.pluck une valeur pour franchisé_id en utilisant la valeur de store_name? Il y a une relation 1: 1 entre ces deux champs, donc même obtenir le "first found" franchisé_id est bien. Merci!

Répondre

3

Vous pourriez faire quelque chose comme ça pour obtenir vos paires id/nom dans l'ordre souhaité:

var map_id_to_name = function(m, o) { 
    m[o.franchisee_id] = o.store_name; 
    return m; 
}; 
var arrayify = function(name, id) { 
    return [ name, id ]; 
}; 
var stores = _(data).chain() 
        .reduce(map_id_to_name, { }) 
        .map(arrayify) 
        .sortBy(_.first) 
        .value(); 

Démo: http://jsfiddle.net/ambiguous/9xxS6/

Cela vous donnera un tableau de tableaux en stores que vous pouvez tourner à travers pour construire votre <option> s; stores ressemblera à ceci:

[ 
    [ "Store 1", "id01" ], 
    [ "Store 2", "id02" ], 
    ... 
] 

Le nom du magasin sera dans la première entrée des réseaux internes et l'ID de franchise dans le second. Le tout sera trié par nom de magasin. Si vous voulez un tri insensible à la casse, vous pouvez plutôt .sortBy(function(a) { return a[0].toLowerCase() }) à la place.

Le reduce(map_id_to_name, { }) collecte les paires identifiant/nom uniques en utilisant un objet pour appliquer automatiquement l'unicité (les clés d'un objet sont uniques après tout). Puis map(arrayify) convertit l'objet en un tableau de tableaux afin que vous puissiez trier les choses. Vous pourriez utiliser un tableau d'objets à la place, ce serait juste une petite modification aux appels map et sortBy.

1

Une approche différente, extraire les informations souhaitées à partir des objets, puis filtrer le tableau résultant pour obtenir des objets uniques:

var stores = _(data).chain() 

// convert each object to {store_name: ..., franchisee_id: ...} 
.map(function(m) { 
    return _.pick(m, "store_name", "franchisee_id"); 
}) 

//keep one of each 
//can be shortened to .uniq(_.property('franchisee_id')) 
.uniq(function(m) { 
    return m.franchisee_id; 
}) 

//sort by name 
.sortBy("store_name") 

//and get the array 
.value(); 

Votre tableau finale ressemblerait

[ 
    {store_name: "Store 1", franchisee_id: "id01"}, 
    {store_name: "Store 2", franchisee_id: "id02"} 
] 

Et une démo de jouer avec http://jsfiddle.net/mr82s/


Et avec un lit pour TLE _.mixin magique, vous pouvez encore se condenser à

_.mixin({ 
    properties: function() { 
     var args = _.toArray(arguments); 
     return function(obj) { 
      return _.pick(obj, args); 
     }; 
    } 
}); 

var stores = _(data).chain() 
.map(_.properties("store_name", "franchisee_id")) 
.uniq(_.property('franchisee_id')) 
.sortBy("store_name") 
.value() 

http://jsfiddle.net/nikoshr/mr82s/1/

+0

C'est une belle façon de le faire et peut-être plus clair que 'reduce' faire double. –