TypeScript:根据共享属性对项目进行分组并为其分配groupID

问题描述 投票:0回答:1

我想实现一个执行以下操作的函数:

  • 采用产品数组作为参数
  • 返回一系列新的产品,每个产品都有一个新的
    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
}
]
javascript typescript algorithm functional-programming
1个回答
0
投票

groupProductsBySharedAttributes
功能中 首先,您将初始化一个名为
Map
groupIdMap
对象,您将在其中存储
Stringify
groupIfIdentical
键的对象的
product
版本作为键,将 groupId 作为值,您还将初始化一个名为
groupedProducts
的新数组,但插入
groupId
后,您将循环遍历
products
数组,检查
key
是否存在于
groupIdMap
中,如果存在,则它们是相同的,如果不保存新的
key
groupId
(递增 1 后),并且在这两种情况下推入
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);

游乐场

© www.soinside.com 2019 - 2024. All rights reserved.