2013-08-13 14 views
6

Ponownie zaimplementowałem własną wersję tego, czego potrzebuję, ale podejrzewam, że jest ona już zawarta w podkreśleniu, ponieważ jest tak prosta i tak ściśle powiązana z wieloma innymi funkcjami. Ale nie mogę wymyślić, jak to nazwać.Jaki jest obiektowy odpowiednik _.pluck

Zasadniczo potrzebuję wersji _.pluck, która działa z obiektami i zwraca obiekt zamiast tablicy (z przypisanymi kluczami).

Tak więc, na przykład, gdybym miał przedmiot takiego:

elements: { 
    steam: { 
     temperature: 100, 
     color: 'orange', 
     state: 'gas' 
    }, 
    water: { 
     temperature: 50, 
     color: 'blue', 
     state: 'liquid' 
    }, 
    ice: { 
     temperature: 0, 
     color: 'white', 
     state: 'solid' 
    } 
} 

chciałbym zadzwonić _.something(elements, 'temperature')

i mieć go zwrócić

{ 
    steam: 100, 
    water: 50, 
    ice: 0 
} 

Zamiast _.pluck(elements, 'temperature') który zwraca

[100, 50, 0] 

Na czym polega ta transformacja i czy jest już uwzględniona w znaku podkreślenia? Sam napisałem szybką wersję z każdą pętlą jQuery, ponieważ bardziej kojarzę jQuery z podkreśleniem (zawartym poniżej), ale wolałbym użyć jej z biblioteki, jeśli to możliwe.

$.objPluck = function(obj, key) { 
    var ret = {}; 
    $.each(obj, function(k, value) { 
     ret[k] = value[key]; 
    }); 
    return ret; 
} 
+0

Istnieje 'Array.map' [metoda] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map), która zasadniczo jest tym, co robisz , ale z obiektem – Ian

+1

Czy istnieje sposób na zachowanie 'Array.map' zachowując klucze? –

+1

Nie jestem pewien, czy rozumiem co masz na myśli. A tak czy inaczej, miałem na myśli tylko twoje początkowe zainteresowanie: "Ale nie mogę wymyślić, jak to nazwać". Z tablicami, nazwałbym to "mapowaniem" – Ian

Odpowiedz

8

Nie ma sposobu, aby zrobić dokładnie to na podkreślenie 1.4.4, ale jeśli chcesz pozostać w podkreślenia, można zrobić

_.object(_.keys(elements), _.pluck(elements, 'temperature')) 

Demo at jsfiddle uprzejmości bfavaretto


Z podkreśleniem 1.8.3, można to zrobić zwięźle z _.mapObject(elements, 'temperature');.

Updated demo

+2

Zamierzałem opublikować dokładnie ten sam kod. Oto jsfiddle, aby to zademonstrować: http://jsfiddle.net/PfZwx/ – bfavaretto

+0

@bfavaretto przegłosował twój komentarz, ponieważ zapomniałem dodać moje skrzypce. Widziałem też 4 sekundy, kiedy twój post był gotowy! :-P – Mathletics

+0

To było rzeczywiście 12 sekund! :) – bfavaretto

0

Można użyć JavaScript for-in loop iterację kluczy obiektu:

var list = []; 

// Iterate through each object key, and pick wanted the values. 
for(var name in obj) 
{ 
    if (obj.hasOwnProperty(name) && name === "temperature") 
    { 
     list.push(obj[name]); 
    } 
} 

Powyższe jest uproszczony przykład, ale powinieneś być w stanie łatwo zmodyfikować, aby ująć go w bardziej ogólna funkcja. Poza tym nie musisz używać tutaj JQuery - natywna implementacja JavaScript będzie szybsza.

Kontrola obj.hasOwnProperty(name) jest zalecana przez JSLint.

3

na lodash (podobne do podkreślenia), można użyć _.mapValues(elements,'temperature').
to powrót {steam: 100, water: 50, ice: 0}

lodash Ref: _.mapValues

przy okazji można wykorzystać _.mapKeys zbudować obiekt mieszania w jednej linii
_.mapKeys(elements,'color') //{orange: Object, blue: Object, white: Object}

6

Warto dodać tu rozwiązanie, które wykorzystuje ES6 funkcje strzałek etc:

Object.keys(elements).map(f=>elements[f].temperature) 

Należy pamiętać, że to nie będzie działać na starych er javascript engines, ale w node.js 0.12 z --harmony działa świetnie, lub z node.js 4.x i później. Właśnie przetestowałem to w Chrome 46 i działa dobrze.

Ma tę zaletę, że nie potrzebuje żadnych dodatkowych bibliotek, takich jak podkreślenia lub lodash, ale oczywiście działa tylko na nowych silnikach JS.

+1

w notacji ES6: Object.keys (elements) .map (function (f) {return elements [f] .temperature}) – egidiocs

+1

Ale gdzie jest zabawa? ;-) – taxilian

+0

użyteczne 4 ktoś może ... – egidiocs

0

W nowszych wersjach jest faktycznie wbudowana funkcja, która to robi.

Jeśli podasz ciąg, zamiast funkcji, na mapObject, zinterpretuje to jako nazwę właściwości i będzie zachowywał się jak "pluckObject". Większość funkcji jest zaskakująco liberalnych w tym, co akceptują.

> _.mapObject(elements,'temperature') 
Object {steam: 100, water: 50, ice: 0} 

Jeśli chcesz wyraźną funkcję do tego celu, można spojrzeć jak _.pluck jest implemented i napisać własną analogiczną wersję:

_.mixin({ 
    pluckObject: function(obj, key) { 
    return _.mapObject(obj, _.property(key)); 
    } 
}); 

jest to raczej zbędne, ale to sprawia, że ​​swoje intencje jaśniejsze.

0

Dla kogo może zainteresować - Na dzień dzisiejszy najlepszą praktyką jest używanie wbudowanych bibliotek js zamiast zewnętrznych bibliotek.

Object.values(elements).map(elem => elem.temperature).

Powiązane problemy