Подтвердить что ты не робот

Есть ли способ переименовать js-объекты с помощью underscore.js

Мне нужно преобразовать объект js в другой объект для передачи на серверную почту, где имена ключей отличаются, например,

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

необходимо включить

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

где у меня есть lookup obj для отображения всех ключей

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

Есть ли функция, доступная в underscore.js или jQuery, которую я могу использовать, выполняет эту функцию?

спасибо

4b9b3361

Ответ 1

Насколько я знаю, в одну из этих двух библиотек нет функции. Вы можете сделать свой собственный довольно легко: http://jsfiddle.net/T9Lnr/1/.

var b = {};

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

Ответ 2

Я знаю, что вы не упомянули lodash, и ответы уже решают проблему, но кто-то другой может воспользоваться альтернативой.

Как упоминалось в комментариях @CookieMonster, вы можете сделать это с помощью _.mapKeys:

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

И скрипка: http://jsfiddle.net/cwkwtgr3/

Ответ 3

Подобно @pimvdb, вы также можете сделать это с помощью _.reduce:

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

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

Ответ 4

Вы можете скопировать значения в новые свойства со стандартным JavaScript и удалить исходные свойства с пропуском, как показано ниже:

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

Ответ 5

Здесь было решено fooobar.com/questions/124173/...

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

а также отображение старых и новых значений, таких как

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

И затем, используя _.map и _.transform, вы можете преобразовать объект, как этот

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;
    });
});

Ответ 6

Нет никакой функции в любой библиотеке, которая явно переименовывает ключи. Ваш метод также является самым быстрым (см. тесты jsperf). Лучше всего, если это возможно, реорганизовать либо клиентскую, либо серверную часть кода объекты одинаковы.

Ответ 7

Почему бы вам не использовать эту простую java script? Значение любой пары ключ: значение должно быть строкой/числом/булевым.

<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>

Ответ 8

У меня есть оператор преобразования и просто хотел бы применить его ко всем ключам. Я раздвоил скрипку pimvdb, чтобы создать простой пример. В этом случае он заглаживает ключ. И он динамически строит ключевую карту, которая мне нужна для обеспечения работы (спасибо JSFiddle).

Вот измененный код:

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;
});

Скрипка: http://jsfiddle.net/mr23/VdNjf/

Ответ 9

// 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();
}

Это может быть медленнее, чем приведенные выше ответы.

Ответ 10

Как user2387823 говорил выше, используя пропустить - отличный вариант. Например, вы могли бы написать что-то вроде этого

function updateObjKey(obj, currentKey, newKey) {
    var keyValue = obj[currentKey];
    obj = _.omit(obj, [currentKey]);
    obj[newKey] = keyValue;
    return obj;
  }

Ответ 11

эта версия ES2015/2017 🧙‍♂️

function objectMap(source,keyMap) {
    return Object.entries(keyMap).reduce((o,[key , newKey]) => {
            o[newKey]=source[key]
            return o;},{})
}

const obj = {
    name : "Foo",
    amount: 55,
    reported : false,
    date : "10/01/2001"
    }
    
const  serverKeyMap = {
    name : "id",
    amount : "total",
    reported : "updated",
    date : "issue"
    }
    
const result = objectMap(obj,serverKeyMap);

console.log('🎬 =>' , result);