2012-01-05 7 views
46

muszę konwertować obiekt js do innego obiektu do przejścia na stanowisku serwerze gdzie nazwy klawiszy różnią się na przykładCzy istnieje jakiś sposób, aby zmienić nazwę obiektu js używając klawiszy underscore.js

var a = { 
    name : "Foo", 
    amount: 55, 
    reported : false, 
    ... 
    <snip/> 
    ... 
    date : "10/01/2001" 
    } 

musi przekształcić

a = { 
    id : "Foo", 
    total : 55, 
    updated: false, 
    ... 
    <snip/> 
    ... 
    issued : "10/01/2001" 
    } 

gdzie mam OBJ odnośnika dostępne dla mapowania wszystkie klucze

var serverKeyMap = { 
    name : "id", 
    amount : "total", 
    reported : "updated", 
    ... 
    date : "issue" 
    } 

Czy istnieje funct jon dostępne w underscore.js lub jQuery, z których mogę korzystać, która wykonuje tę funkcjonalność?

dziękuję

+3

Nie podkreślenia, ale ma miejsce na [_.mapKeys] (https://lodash.com/docs#mapKeys) w celu modyfikacji kluczy obiektu. – CookieMonster

Odpowiedz

26

O ile mi wiadomo, nie ma funkcji wbudowanej w żadnej z tych dwóch bibliotek. Możesz jednak łatwo stworzyć własne: http://jsfiddle.net/T9Lnr/1/.

var b = {}; 

_.each(a, function(value, key) { 
    key = map[key] || key; 
    b[key] = value; 
}); 
1

Nie ma żadnej funkcji w żadnej bibliotece, która jawnie zmienia nazwy kluczy. Twoja metoda jest również najszybsza (patrz: jsperf tests.) Twój najlepszy zakład, jeśli to możliwe, polega na refaktoryzacji kodu po stronie klienta lub kodu po stronie serwera, aby obiekty były takie same.

+1

Przypadki testowe w benchmarku nawet nie wyglądają na równe. – meandre

1

Dlaczego nie używasz tego prostego skryptu java? Wartość dowolnej pary klucz: wartość powinna być łańcuchem/liczba/Boolean.

<script type="text/javascript">  
    var serverKeyMap = { 
     name : "id", 
     amount : "total", 
     reported : "updated" 
    }; 

    var a = { 
     name : "Foo", 
     amount: 55, 
     reported : false 
    }; 

    var b={}; // b is object where you will get your output 

    for(i in serverKeyMap) b[serverKeyMap[i]]=a[i]; 

    console.log(b); // It gives what you need. 

</script> 
1

Mam operatora transformacji i chciałbym go zastosować do wszystkich kluczy. Rozwinąłem skrzypce pimvdb, by stworzyć prosty przykład. W tym przypadku kapitalizuje klucz. I dynamicznie buduje mapę klawiszy, której potrzebowałem, aby zapewnić pracę (dzięki JSFiddle).

Oto kod Zmieniono:

var keymap = {}; 
_.each(a, function(value, key) { 
    var oldkey = key; 
    key = capitalize(key); 
    keymap[oldkey] = key; 
}); 
_.each(a, function(value, key) { 
    key = keymap[key] || key; 
    b[key] = value; 
}); 

Fiddle: http://jsfiddle.net/mr23/VdNjf/

+0

Chociaż przykład jest wymyślony, w rzeczywistości użyłem tego do zbudowania mapy klawiszy "czyszczenia" przy użyciu pierwszego rekordu zbioru danych, a następnie zastosować go do pozostałych (które mogą zawierać dodatkowe "obciążenia" danych). – mr23

+0

Skończyłem z użyciem powyższego rozwiązania _.replace(), ale zacząłem od spojrzenia na twoje rozwiązanie i plunkr. działa dobrze. dzięki – FireDragon

36

podobne do @pimvdb, można również zrobić z _.reduce:

_.reduce(a, function(result, value, key) { 
    key = map[key] || key; 
    result[key] = value; 
    return result; 
}, {}); 

Fiddle: http://jsfiddle.net/T9Lnr/39/

+1

skrzypce już nie działa – wegginho

+0

wydaje się nadal pracować dla mnie @wegginho, drukuje na konsolę – dule

+0

Otrzymuję błąd, który podkreślenia nie jest zdefiniowany – wegginho

34

Wiem, że nie wspomniałeś o lodash, a odpowiedzi już rozwiązały problem, ale gdy przyszedłem tutaj szukając sposobu, by to zrobić, pomyślałem, że ktoś inny może skorzystać z alternatywy.

Jak @CookieMonster wspomniano w komentarzach, można to zrobić z _.mapKeys:

_.mapKeys(a, function(value, key) { 
    return serverKeyMap[key]; 
}); 

a skrzypce: http://jsfiddle.net/cwkwtgr3/

+1

Efekty uboczne są mocne z tym. – DFlores009

2

To zostało rozwiązane tutaj https://stackoverflow.com/a/30940370/1360897

var keyMapping = {'PropertyA': 'propertyA', ..., 'PropertyF': 'propertyNEW'} 

a także mapowanie starych i nowych wartości, takich jak ten

var valueMapping = {'Y': true, 'F': false} 

A następnie za pomocą _.map i _.transform można przekształcić obiekt, jak to

var result = _.map(allItems, function(currentObject) { 
    return _.transform(currentObject, function(result, value, key) { 
     if (key === 'PropertyF' || key === 'PropertyG') { 
      value = valueMapping(value); 
     } 
     result[keyMapping[key]] = value; 
    }); 
}); 
10

Można skopiować wartości z nowymi właściwościami ze standardowym JavaScript i usunąć oryginalne właściwości z pominąć, co następuje:

a.id = a.name; 
a.total = a.amount; 
a.updated = a.reported; 
a = _.omit(a, 'name', 'amount', 'reported'); 
+0

Proszę dodać wyjaśnienie. Obecnie Twoja odpowiedź jest oznaczona jako "niska jakość" i może zostać usunięta. –

0

jak user2387823 mówił above użyciu pominąć jest świetnym rozwiązaniem. Na przykład można napisać coś takiego

function updateObjKey(obj, currentKey, newKey) { 
    var keyValue = obj[currentKey]; 
    obj = _.omit(obj, [currentKey]); 
    obj[newKey] = keyValue; 
    return obj; 
    } 
1
// key_map: {old_name1: new_name1, ... } 
function rename_keys(object, key_map, is_picked=false){ 
    keys = _.keys(key_map); 
    new_keys = _.values(key_map); 
    picked = _.pick(object, keys); 
    renamed = _.object(new_keys, _.values(picked)); 
    if(is_picked) return renamed; 

    return _.chain(object).omit(keys).extend(renamed).value(); 
} 

To może być wolniejszy niż powyższych odpowiedzi.

Powiązane problemy