Способ переименования ключей объектов в другой формат

#javascript #lodash

#javascript #Lodash

Вопрос:

возникла проблема с переименованием ключей объектов простым и разумным способом. Иметь следующий объект:

 expanded: false
fontColor: "#123456"
subjectTag: null
title: "Contact us asap"
titleColor: "#654321"
titleSubject: "Call US"
__typename: "alert"
_id: "alertx"
  

в следующий формат:

 expanded: false
font_color: "#123456"
subject_tag: null
title: "Contact us asap"
title_color: "#654321"
title_subject: "Call US"
__typename: "alert"
_id: "alertx"
  

Ключи находятся в разных форматах, и я боролся с этим.
Также хотелось удалить: __typename и _id ключи.

Я начал использовать функцию с Lodash mapKeys, но заблудился:

 const modifiedObject = mapKeys(objectX, (value, key) => {
   return key   '_';
});
  

Спасибо!

Комментарии:

1. Вы хотите преобразовать camelCase в snake_case?

Ответ №1:

Сопоставьте ключи и используйте _.snakeCase() их для преобразования в требуемый формат:

 const obj = {"expanded":false,"fontColor":"#123456","subjectTag":null,"title":"Contact us asap","titleColor":"#654321","titleSubject":"Call US","__typename":"alert","_id":"alertx"}

const result = _.mapKeys(obj, (v, k) => _.snakeCase(k))

console.log(result)  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>  

Если вы хотите избежать преобразования / удаления ключей, начинающихся с символа подчеркивания ( _ ), вы можете использовать k.startsWith('_') для его проверки. Чтобы избежать преобразования, используйте троичный in _.mapKeys() и решите конвертировать или нет, проверив, содержит ли ключ _ . Если вы хотите их удалить, используйте _.omit() .

 const obj = {"expanded":false,"fontColor":"#123456","subjectTag":null,"title":"Contact us asap","titleColor":"#654321","titleSubject":"Call US","__typename":"alert","_id":"alertx"}

console.log(_.mapKeys(obj, (v, k) => k.startsWith('_') ? k : _.snakeCase(k)))

console.log(_.mapKeys(_.omitBy(obj, (v, k) => k.startsWith('_')), (v, k) => _.snakeCase(k)))  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>  

Комментарии:

1. Отличное решение, как я могу избежать изменения: «__typename» и «_id» или удаления их из объекта?

2. Я пытался избежать изменения приведенных выше ключей на snake_case, используя это, но по какой-то причине он возвращает мне только один ключ: mapKeys(initialValues, (v, k) => { k.split(/(?=[A-Z])/) .join(‘_’) .toLowerCase(); })

3. Ваш код не работает, потому что вы не возвращаете новый ключ, а возврат не похож на возврат undefined . Удалите фигурные скобки или добавьте return .

Ответ №2:

Вы можете сделать следующее,

 const obj = {
  expanded: false,
  fontColor: "#123456",
  subjectTag: null,
  title: "Contact us asap",
  titleColor: "#654321",
  titleSubject: "Call US",
  __typename: "alert",
  _id: "alertx",
}
const arrWithNewKey = Object.keys(obj).map((key) => {
   if(key === '__typename' || key === '_id') return null; // to remove __typename and _id
   const newKey = key.replace(/([A-Z])/g, (v) => { return '_' v.toLowerCase(); }); // converting thisKey to this_key
   return {[newKey]: obj[key] };
}).flat();
var newObj = Object.assign({}, ...arrWithNewKey );
  

Комментарии:

1. Это хорошее решение, а также позволяет избежать случайного использования этих свойств: _id и __typename, это может быть с меньшим и более коротким кодом?

2. ПРИВЕТ, я обновил код, чтобы удалить __typename и _id . Но я не могу придумать более короткий код для этого.

Ответ №3:

Вы можете использовать reduce с Object.keys()

 const obj = {
  expanded: false,
  fontColor: "#123456",
  subjectTag: null,
  title: "Contact us asap",
  titleColor: "#654321",
  titleSubject: "Call US",
  __typename: "alert",
  _id: "alertx",
};

const snakeCase = str => str.replace(/_/g, '').replace(/[A-Z]/g, word => `_${word.toLowerCase()}`);
const transformObj = o => Object.keys(o).reduce((acc, k) => ({...acc, [snakeCase(k)]: o[k] }), {});

console.log(transformObj(obj));  

Комментарии:

1. Это хорошее решение, а также позволяет избежать случайного использования этих свойств: _id и __typename, это может быть с меньшим и более коротким кодом?

2. @tommyahav10 проверьте мое обновление, я преобразовал их в две разные функции, чтобы я мог создавать однострочные функции и вызывать их независимо, таким образом, вы можете повторно использовать не только для одного времени / объекта. Хотя он немного короче, я думаю, что он теряет удобочитаемость, если вы не знакомы с функциями со стрелками