ค้นหาเว็บไซต์

javascript - วิธีที่ดีที่สุดในการแปลงชื่อวัตถุเป็นรูปแบบที่ต้องการคืออะไร


วิธีที่ดีที่สุดในการแมปคุณสมบัติของวัตถุทั้งหมดไปยังรูปแบบวัตถุใหม่ที่มีชื่อคุณสมบัติแตกต่างกัน ตัวอย่าง:

นี่คือรูปแบบที่ต้องการ

const person = {
  firstName: 'john',
  lastName: 'doe',
  houses: [{ housName: 'Kruger' }]
}

และฉันมีวัตถุสองชิ้นนี้

const person1 = {
  prenom: 'john', //this should be mapped to the firstName
  nom: 'doe', //this should be mapped to the lastName
  houses: [{ house_name: 'Kruger' }]
}
const person2 = {
  name: 'john', // this should be mapped to the firstName
  familyName: 'doe', // this should be assigned to the lastName
  Houses: [{ House_Name: 'Kruger' }]
};

เป้าหมายคือทำให้ person1 และ person2 พร้อมคุณสมบัติทั้งหมดและคุณสมบัติย่อยของพวกเขาดูเหมือนคน

ฉันได้พยายามแล้ว

export class Person {
  @Expose({ name: 'prenom' })
  firstName: string;

  @Expose({ name: 'nom' })
  lastName: string;

  }
}

//this should give a formatted version from person1 ==> person
const formatted = plainToClass(person1,Person)

อย่างไรก็ตาม สิ่งนี้จะต้องทำให้ฉันสร้างหลายเวอร์ชันของคลาส Person ซึ่งไม่สะดวกหากเราต้องการใช้คลาสนี้สำหรับการพิมพ์

คำตอบ #1

ขั้นแรกคุณต้องรับคีย์และค่าทั้งหมดของ object ด้วย Object.entries(obj) จากนั้นในแต่ละคีย์เราจำเป็นต้องเปลี่ยนมันจาก pascal case เป็น camel case ก่อนอื่นเราต้องเปลี่ยนสตริงให้เป็น lower case แล้วจึงใช้ replace กับ /_([a-z])/gi ซึ่งจับตัวอักษรตัวแรกหลังเครื่องหมายขีดล่าง _ และเปลี่ยนมันเป็น Upper case

str.toLowerCase().replace(/_([a-z])/gi, function (g) { return g[1].toUpperCase(); });

จากนั้นลดขนาดอาร์เรย์และแปลงกลับเป็นอ็อบเจ็กต์

const mapToCamelCase = (obj) => {
    return Object.entries(obj).reduce((acc, [key,value]) => {
        var keyCamelCased = toCamelCase(key)
       acc[keyCamelCased] = value
       return acc
    }, {})
}

const person1 = {
  first_name: 'john',
  last_name: 'doe',
  houses: [{ house_name: 'Kruger' }]
}
const person2 = {
  First_Name: 'john',
  Last_Name: 'doe',
  Houses: [{ House_Name: 'Kruger' }]
};


const toCamelCase = (str) => {
  return str.toLowerCase().replace(/_([a-z])/gi, function (g) { return g[1].toUpperCase(); });
}


const mapToCamelCase = (obj) => {
    return Object.entries(obj).reduce((acc, [key,value]) => {
        var keyCamelCased = toCamelCase(key)
       acc[keyCamelCased] = value
       return acc
    }, {})
}

console.log(mapToCamelCase(person1))
console.log(mapToCamelCase(person2))

คำตอบ #2

ฟังก์ชันแบบเรียกซ้ำง่าย ๆ สามารถทำการแปลงชื่อที่คุณต้องการได้ ซึ่งจะสามารถทำงานได้กับข้อมูลนำเข้าที่มีความลึกของรายการใด ๆ

การใช้ Object.entries() และ Object.fromEntries()

const person1 = { first_name: "john", last_name: "doe", houses: [{ house_name: "Kruger" }], }; const person2 = { First_Name: "john", Last_Name: "doe", Houses: [{ House_Name: "Kruger" }], }; const person3 = { first_name: "john", last_name: "doe", houses: [ { house_name: "Kruger", phone_numbers: [{ ext_code: "+54", phone_number: 232242323 }], }, ], };

const formatName = (str) => {
  return str
    .split("_")
    .map(
      (w, index) =>
        (index > 0 ? w[0].toUpperCase() : w[0].toLowerCase()) + w.substring(1)
    )
    .join("");
};

const formatNames = (input) => {
  if (Array.isArray(input)) {
    return input.map((item) => formatNames(item));
  } else if (typeof input === "object") {
    return Object.fromEntries(
      Object.entries(input).map(([key, value]) => [
        formatName(key),
        formatNames(value),
      ])
    );
  }
  return input;
};

console.log(formatNames(person1));
console.log(formatNames(person2));
console.log(formatNames(person3));

หมายเหตุ: หากคุณทำให้ฟังก์ชัน formatName เป็นอาร์กิวเมนต์ของ formatNames แล้ว formatNames จะมีความยืดหยุ่นมากขึ้นเนื่องจากสามารถใช้เพื่อสร้างอ็อบเจ็กต์ที่มีรูปแบบชื่อแตกต่างกันได้