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);
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);