Используйте regex для переименования ключей массива объектов
У меня есть массив объектов. Каждый объект имеет много ключей (более 100), и некоторые из этих ключей могут иметь специальные символы, которые я хотел бы удалить.
Я стараюсь делать то, что я хочу, таким образом:
const result = data.map(datum => {
const keys = Object.keys(datum)
const replacedKeys = keys.map(key => {
const newKey = key.replace(/[.|&;$%@%"<>+]/g, '')
})
// ??
})
Но я уверен, что это не правильный путь..
Ответы
Ответ 1
Вы можете сопоставить новый объект с новым ключом и создать один объект с Object.assign
.
const result = data.map(datum => Object.assign(...Object
.keys(datum)
.map(key => ({ [key.replace(/[.|&;$%@%"<>+]/g, '')]: datum[key] }))
));
Ответ 2
С методом ES8 Object.fromEntries
, который уже нашел свой путь в FireFox, вы можете сделать:
const sanitiseKeys = o => Object.fromEntries(Object.entries(o).map(([k,v]) =>
[k.replace(/[.|&;$%@%"<>+]/g,""), v]));
// Example use:
var data = [{ "name#": "John" }, { "@key": 2 }];
data = data.map(sanitiseKeys);
console.log(data);
Ответ 3
Вы можете преобразовать простой объект JavaScript в JSON
с помощью JSON.stringify()
и сопоставить свойство допустимого JSON
с помощью String.prototype.replace()
, а затем преобразовать обратно в простой объект JavaScript с помощью JSON.parse()
.
Удалено "
из класса символов, поскольку допустимое свойство JSON
заключено в двойные кавычки "
.
RegExp
([.|&;$%@%<>+]+)(?=([^\1]+|)":)
создает группу захвата, содержащую класс символов, и соответствует классу символов, за которым следуют один или несколько символов, которых нет в классе символов, с последующей закрывающей двойной кавычкой имени свойства "
последующим двоеточием или двойными кавычками с последующим двоеточием.
Соответствующий класс символов может быть заменен пустой строкой ''
или любым другим символом.
let o = {"a.B|c&D;0$_%@q%<Z>5+":1};
console.log(o);
o = JSON.parse(JSON.stringify(o).replace(/([.|&;$%@%<>+]+)(?=([^\1]+|)":)/g, ''));
console.log(
JSON.stringify(o)
, /[.|&;$%@%<>+]+/.test(Object.keys(o)[0]) // false
);
Ответ 4
Подумайте об использовании Array#reduce()
для агрегирования значений для ключей вашего входного объекта. Причина этого заключается в том, что ваша санация ключа (то есть удаление нежелательных символов из ключей) может привести к тому, что отдельные пары ключ/значение вашего входного объекта "уменьшатся", так что санированная клавиша эффективно связана с несколькими значениями. Например, входной объект, такой как:
const data = {
'key' : 'value0',
'key&&&' : 'value1',
'key$%<>' : 'value2'
}
будет (в зависимости от вашей гигиены) привести к выходному объекту с одним key
относящимся к нескольким значениям:
const data = {
'key' : 'value0', // what about value1, value2 ?
}
Чтобы решить эту проблему, вы можете рассмотреть возможность объединения значений с общими очищенными ключами в массив, как показано ниже:
const data = {
'key' : 'value0',
'key&&&' : 'value1',
'key$%<>' : 'value2',
'foo' : 'value3'
}
const result = Object.entries(data).reduce((obj, [ key, value ]) => {
const sanitizedKey = key.replace(/[.|&;$%@%"<>+]/g, '');
const objValue = obj[ sanitizedKey ]
/*
Account for conflicting keys after santizing by grouping
values in a nested array
*/
if(objValue) {
obj[ sanitizedKey ] = [value].concat(objValue)
}
else {
obj[ sanitizedKey ] = value
}
return obj;
}, {});
console.log(result)
Ответ 5
Это решение основано на String.prototype.replace()
, поэтому оно может принимать String
или RegExp
в качестве источника и допускает замену. Имейте в виду, что он не очень производительный, но использует только чистые функции:
const data = {
someKey: 1,
some0Key: 1,
some1Key: 1,
some2Key: 1,
some3Key: 1,
some4Key: 1,
some5Key: 1,
some6Key: 1,
some7Key: 1,
some8Key: 1,
some9Key: 1,
some10Key: 1,
some11Key: 1,
some12Key: 1,
some13Key: 1,
some14Key: 1,
some15Key: 1,
};
// simple equivalent of proposed Object.fromEntries()
const fromEntries = (entries) =>
entries.reduce((obj, [key, value]) => ({
[key]: value,
...obj
}), {});
const replaceObjectKeys = (obj, from, to) =>
fromEntries(
Object.entries(obj)
.map(([key, value]) => [key.replace(from, to), value]));
console.log(replaceObjectKeys(data, /Key$/, 'prop'));