Есть ли умный (то есть оптимизированный) способ переименования ключа в javascript-объекте?JavaScript: Object Переименовать ключ
Не-оптимизированный способ будет:
o[ new_key ] = o[ old_key ];
delete o[ old_key ];
Есть ли умный (то есть оптимизированный) способ переименования ключа в javascript-объекте?JavaScript: Object Переименовать ключ
Не-оптимизированный способ будет:
o[ new_key ] = o[ old_key ];
delete o[ old_key ];
Вы можете обернуть работу в функции и присвоить его Object
прототип. Возможно, используйте свободный интерфейс, чтобы сделать несколько переименований.
Object.prototype.renameProperty = function (oldName, newName) {
// Do nothing if the names are the same
if (oldName == newName) {
return this;
}
// Check for the old property name to avoid a ReferenceError in strict mode.
if (this.hasOwnProperty(oldName)) {
this[newName] = this[oldName];
delete this[oldName];
}
return this;
};
ECMAScript 5 Удельное
Я хочу синтаксис не был этот комплекс, но это, безусловно, приятно иметь больше контроля.
Object.defineProperty(
Object.prototype,
'renameProperty',
{
writable : false, // Cannot alter this property
enumerable : false, // Will not show up in a for-in loop.
configurable : false, // Cannot be deleted via the delete operator
value : function (oldName, newName) {
// Do nothing if the names are the same
if (oldName == newName) {
return this;
}
// Check for the old property name to
// avoid a ReferenceError in strict mode.
if (this.hasOwnProperty(oldName)) {
this[newName] = this[oldName];
delete this[oldName];
}
return this;
}
}
);
@ChaosPandion извините, но я действительно устал от ошибки JS-кода , Я в настоящее время пишу Руководство (https://github.com/BonsaiDen/JavaScript-Garden) обо всех причудах (включая тот, который вы сейчас исправили), это могло бы привести меня в какой-то режим тиража;) (Удалено -1 сейчас) –
@Ivo - Не могли бы вы объяснить, почему вы чувствуете, что продление прототипа плохое? Прототипы были сделаны для продления ребенка! – ChaosPandion
@ChaosPandion Не ** ** туземцы **, потому что они вводят весь беспорядок с 'in' и т. Д. Prototype.js - отличный пример ** почему ** это плохо, даже его разработчики признали, что это было плохо чтобы использовать его для библиотеки. –
Я бы сказал, что было бы лучше, с концептуальной точки зрения, чтобы просто оставить старый объект (один из веб-службы), как это, и поместить необходимые значения в новом объекте. Я предполагаю, что вы извлекаете определенные поля в какой-то момент или в любом случае, если не на клиенте, то, по крайней мере, на сервере. Тот факт, что вы выбрали имена полей, которые являются теми же, что и в веб-службе, только в нижнем регистре, на самом деле не изменяет это. Таким образом, я бы посоветовал сделать что-то вроде этого:
var myObj = {
field1: theirObj.FIELD1,
field2: theirObj.FIELD2,
(etc)
}
Конечно, я делаю все виды предположений здесь, которые не могут быть истинными. Если это не относится к вам, или если оно слишком медленное (не так ли? Я не тестировал, но, я думаю, разница становится меньше по мере увеличения количества полей), пожалуйста, игнорируйте все это:
Если вы не хотите этого делать, и вам нужно только поддерживать определенные браузеры, вы также можете использовать новые геттеры, чтобы также вернуть «uppercase (field)»: см. http://robertnyman.com/2009/05/28/getters-and-setters-with-javascript-code-samples-and-demos/ и ссылки на этой странице для получения дополнительной информации.
EDIT:
Невероятно, но это также почти в два раза быстрее, по крайней мере, на моей FF3.5 на работе. См: http://jsperf.com/spiny001
Большое спасибо за ваши усилия, но прецедент не управляет статическими объектами, так как их структура и глубина не показаны. Поэтому, если возможно, я хотел бы придерживаться первоначальной сферы вопроса. –
Наиболее полно (и правильно) способ сделать это было бы, я считаю:
if (old_key !== new_key) {
Object.defineProperty(o, new_key,
Object.getOwnPropertyDescriptor(o, old_key));
delete o[old_key];
}
Этот метод гарантирует, что переименовано свойство ведет себя идентично исходному.
Кроме того, мне кажется, что возможность обернуть это в функцию/метод и поместить его в Object.prototype
, не имеет отношения к вашему вопросу.
Это приятное решение только с ES5 с реальным плюсом сохранения всех свойств. Таким образом, это не «оптимизировано», а определенно более точно на ES5. –
поддержал некоторый скептицизм по отношению к writing_things_with_underscores, но, конечно, это было связано с тем, что человек задал вопрос. это правильный ответ на мой взгляд. –
Хотел бы я дать вам +50000 –
Я хотел бы сделать что-то вроде этого:
function renameKeys(dict, keyMap) {
return _.reduce(dict, function(newDict, val, oldKey) {
var newKey = keyMap[oldKey] || oldKey
newDict[newKey] = val
return newDict
}, {})
}
Сделал обновленную версию вашего решения, которое не преобразует статические ключи в «undefined» здесь: https://gist.github.com/diasdavid/f8997fb0bdf4dc1c3543 Тем не менее, проблема по-прежнему не связана с необходимостью переназначить ключи на нескольких уровнях объекта JSON (переназначая вложенные ключи), идеи? –
Лично, самые эффективный способ переименования ключей в объекте без реализации сверхтяжелых плагин и колеса:
var str = JSON.stringify(object);
str = str.replace(/oldKey/g, 'newKey');
str = str.replace(/oldKey2/g, 'newKey2');
object = JSON.parse(str);
Вы также можете обернуть его в try-catch
, если ваш объект имеет недопустимую структуру.Работает отлично :)
ooops! var object = {b: '123', 'c': 'bbb'}; var str = JSON.stringify (объект); str = str.replace (/ b/g, 'newKey'); str = str.replace (/ c/g, 'newKey2'); объект = JSON.parse (str); – BlondinkaBrain
Как это сравнить для скорости? – mix3d
Также возникает потенциальная проблема где-то в datavalues - это та же строка, что и имя старого ключа. – mix3d
Хотя это не дает лучшего решения для переименования ключа, оно обеспечивает быстрый и простой способ ES6 переименовать все ключи в объекте, не изменяя данные, которые они содержат.
let b = {a: ["1"], b:["2"]};
Object.keys(b).map(id => {
b[`root_${id}`] = [...b[id]];
delete b[id];
});
console.log(b);
Заботьтесь о том, что вы сделали и почему? – empiric
Пожалуйста, используйте ссылку [edit], чтобы объяснить, как работает этот код, и не просто указывать код, так как объяснение, скорее всего, поможет будущим читателям. См. Также [ответ]. [источник] (http://stackoverflow.com/users/5244995) –
Согласен. Он не отвечает на вопрос конкретно, но он помог мне в выполнении работы в качестве решения для переименования всех ключей в объекте. Возможно, я пропустил эту тему. –
В случае кто-то должен переименовать список свойств:
function renameKeys(obj, newKeys) {
const keyValues = Object.keys(obj).map(key => {
const newKey = newKeys[key] || key;
return { [newKey]: obj[key] };
});
return Object.assign({}, ...keyValues);
}
Использование:
const obj = { a: "1", b: "2" };
const newKeys = { a: "A", c: "C" };
const renamedObj = renameKeys(obj, newKeys);
console.log(renamedObj);
// {A:"1", b:"2"}
это должно быть принято, отлично работал для моего использования. Мне пришлось преобразовать ответ API, который префиксные имена стран с ненужной строкой. Повернул объект в массив ключей и сопоставил каждую клавишу с помощью метода подстроки и вернул новый объект с новым ключом и значением, индексированным по первому ключу. –
ES6(ES2015)
путь!Нам нужно идти в ногу со временем!
const old_obj = {
k1: `111`,
k2: `222`,
k3: `333`
};
console.log(`old_obj =\n`, old_obj);
// {k1: "111", k2: "222", k3: "333"}
/**
* @description ES6 ...spread & Destructuring Assignment
*/
const {k1: kA, k2: kB, k3: kC,} = {...old_obj}
console.log(`kA = ${kA},`, `kB = ${kB},`, `kC = ${kC}\n`);
// kA = 111, kB = 222, kC = 333
const new_obj = Object.assign(
{},
{
kA,
kB,
kC
}
);
console.log(`new_obj =\n`, new_obj);
// {kA: "111", kB: "222", kC: "333"}
Что вы имеете в виду под "оптимизированы"? Я не думаю, что это может быть более кратким, чем это; нет «переименования» встроенной операции. – Pointy
Это все, что вы можете получить. Я бы позаботился о других вещах в моем заявлении. И кстати, вы имеете дело с объектами, а не с массивами. В JavaScript нет ассоциативных массивов (в строгом смысле). –
Оптимизированный будет либо более быстрым, либо компактным, либо более читаемым. –