Joining lists by shared property

Adding TypeScript solution below that will produce the same result:

interface Item {
    Id: string;
    GTIN?: string;
    Color?: string;
    Material?: string;
    Grams?: number;
}

function joinLists(list1: Item[], list2: Item[]): Item[] {
    const joinedList: Item[] = [];

    list1.forEach(item1 => {
        const matchingItem = list2.find(item2 => item2.Id === item1.Id);
        if (matchingItem) {
            joinedList.push({
                ...item1,
                Material: matchingItem.Material,
                Grams: matchingItem.Grams
            });
        } else {
            joinedList.push(item1);
        }
    });

    return joinedList;
}
joinLists(list1,list2);

@supply-candidate-367

To achieve what you’re asking for you can use the following TypeScript:

interface Item {
    Id: string;
    GTIN?: string;
    Color?: string;
    Material?: string;
    Grams?: number;
}

interface GroupedItem {
    material: string;
    items: Item[];
}

function groupByMaterial(list1: Item[], list2: Item[]): GroupedItem[] {
    const groupedItemsMap: Map<string, Item[]> = new Map();

    // Group items from list2 by Material
    list2.forEach(item => {
        if (item.Material) {
            const material = item.Material.toLowerCase();
            if (!groupedItemsMap.has(material)) {
                groupedItemsMap.set(material, []);
            }
            groupedItemsMap.get(material)?.push(item);
        }
    });

    // Group items from list1 by Material and merge with list2
    list1.forEach(item => {
        const material = item.Material?.toLowerCase();
        if (material && groupedItemsMap.has(material)) {
            groupedItemsMap.get(material)?.push(item);
        } else if (material) {
            groupedItemsMap.set(material, [item]);
        }
    });

    // Convert Map to array of GroupedItem objects
    const groupedItems: GroupedItem[] = [];
    groupedItemsMap.forEach((items, material) => {
        groupedItems.push({ material: material, items: items });
    });

    return groupedItems;
}
groupByMaterial(list1,list2);