javascript - TypeScript: จัดกลุ่มรายการตามคุณสมบัติที่ใช้ร่วมกันและกำหนด groupID ให้พวกมัน
ฉันต้องการสร้างฟังก์ชันที่ทำสิ่งต่อไปนี้:
- ใช้แอเรย์ของสินค้าเป็นอาร์กิวเมนต์
- ส่งคืนอาเรย์ใหม่ของผลิตภัณฑ์ ซึ่งแต่ละผลิตภัณฑ์มีคุณสมบัติ
groupIdใหม่ - ผลิตภัณฑ์ที่แตกต่างกันจะใช้
groupIdเดียวกันหากพวกเขามีคุณสมบัติทั่วไปเหมือนกัน โดยคุณสมบัติจะถูกกำหนดโดยgroupIfIdentical
ดูโครงร่างฟังก์ชันที่นี่:
function groupProductsBySharedAttributes(
products: Product[],
groupIfIdentical: (keyof Product)[],
initialGroupId: string,
) {
}
ผลิตภัณฑ์ที่มีคุณสมบัติเหมือนกันควรถูกจัดกลุ่มแบบนี้:
export function productsAreIdentical(
prod1: Product,
prod2: Product,
groupIfIdentical: (keyof Product)[],
) {
for (const key of groupIfIdentical) {
if (prod1[key] !== prod2[key]) {
return false
}
return true
}
}
ตัวอย่าง :
const prods = [{
country: 'china',
material: 'steel',
sku: 1453
},
{
country: 'china',
material: 'steel',
sku: 4874
},
{
country: 'japan',
material: 'steel',
sku: 4874
},
]
const result = groupProductsBySharedAttributes(prods, ['country', 'material'], 1001)
result = [
{
country: 'china',
material: 'steel',
sku: 1453,
groupId: 1001
},
{
country: 'china',
material: 'steel',
sku: 4874,
groupId: 1001
},
{
country: 'japan',
material: 'steel',
sku: 4874,
groupId: 1002
}
]
คำตอบ #1
ในฟังก์ชัน groupProductsBySharedAttributes ก่อนอื่นคุณจะสร้างวัตถุ Map ที่เรียกว่า groupIdMap ซึ่งคุณจะเก็บเวอร์ชัน Stringify ของวัตถุที่มีคีย์ groupIfIdentical ของ product เป็นคีย์ และ groupId เป็นค่า นอกจากนี้คุณจะสร้างอาร์เรย์ใหม่ที่เรียกว่า groupedProducts ของสินค้าต่าง ๆ แต่หลังจากแทรก groupId แล้ว จากนั้นคุณจะวนลูปผ่านอาร์เรย์ products เพื่อตรวจสอบว่าคีย์ key มีอยู่ใน groupIdMap หรือไม่ ถ้ามี หมายความว่าพวกมันเหมือนกัน ถ้าไม่ ให้บันทึก key ใหม่และ groupId (หลังจากเพิ่มขึ้นหนึ่ง) และในทั้งสองกรณี ให้เพิ่มเข้าไปใน groupedProducts
interface Product {
[key: string]: any;
}
function productsAreIdentical(
prod1: Product,
prod2: Product,
groupIfIdentical: (keyof Product)[]
): boolean {
for (const key of groupIfIdentical) {
if (prod1[key] !== prod2[key]) {
return false;
}
}
return true;
}
function groupProductsBySharedAttributes(
products: Product[],
groupIfIdentical: (keyof Product)[],
initialGroupId: string,
): Product[] {
let groupId = parseInt(initialGroupId); // Convert initialGroupId to an integer for easy incrementation
const groupedProducts: Product[] = [];
const groupIdMap = new Map<string, number>(); // Maps a stringified key to a groupId
products.forEach(product => {
let foundGroup = false;
for (const [key, id] of groupIdMap) {
const keyAttributes = JSON.parse(key);
if (productsAreIdentical(product, keyAttributes, groupIfIdentical)) {
product.groupId = id;
foundGroup = true;
break;
}
}
if (!foundGroup) {
const key = JSON.stringify(
groupIfIdentical.reduce((acc, attr) => {
acc[attr] = product[attr];
return acc;
}, {} as Partial<Product>)
);
if (!groupIdMap.has(key)) {
groupIdMap.set(key, groupId);
product.groupId = groupId;
groupId++;
}
}
groupedProducts.push(product);
});
return groupedProducts;
}
// Example usage
const prods = [
{ country: 'china', material: 'steel', sku: 1453 },
{ country: 'china', material: 'steel', sku: 4874 },
{ country: 'japan', material: 'steel', sku: 4874 }
];
const result = groupProductsBySharedAttributes(prods, ['country', 'material'], '1001');
console.log(result);
สนามเด็กเล่น
