Используйте regex для переименования ключей массива объектов - PullRequest
0 голосов
/ 09 февраля 2019

У меня есть массив объектов.Каждый объект имеет много ключей (более 100), и некоторые из этих ключей могут иметь специальные символы, которые я хотел бы удалить.

Я пытаюсь сделать то, что хочу, таким образом:

const result = data.map(datum => {
  const keys = Object.keys(datum)
  const replacedKeys = keys.map(key => {
    const newKey = key.replace(/[.|&;$%@%"<>+]/g, '')
  })
  // ??
})

Но я уверен, что это не правильный путь ..

Ответы [ 5 ]

0 голосов
/ 09 февраля 2019

В этом решении используется 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'));

fromEntries можно легко переписать в более быструю реализацию за счет введения изменяемых переменных.

0 голосов
/ 09 февраля 2019

С помощью метода 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);

Если еще не реализовано, вот полифилл:

Object.fromEntries = arr => Object.assign({}, ...arr.map( ([k, v]) => ({[k]: v}) ));
0 голосов
/ 09 февраля 2019

Вы можете преобразовать простой объект 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
);
0 голосов
/ 09 февраля 2019

Попробуйте использовать 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)
0 голосов
/ 09 февраля 2019

Вы можете сопоставить новый объект с новым ключом и создать отдельный объект с Object.assign.

const result = data.map(datum => Object.assign(...Object
    .keys(datum)
    .map(key => ({ [key.replace(/[.|&;$%@%"<>+]/g, '')]: datum[key] }))
));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...