Reputation: 1863
I'm trying to group related products together from an API that is quite limited, essentially these related products are just variants in colour. There is a certain naming convention where the variant/colour will be written in the title string as T-Shirt [Red]
or T-Shirt [White]
, so I will be able to parse the title string and look for strings that are equal before any [
character. With this in mind I will need to use .split()
method, however, I have no idea how to approach the comparison aspect, perhaps the .map()
method is the wrong choice here. Any help or pointers would be greatly appreciated.
const clothing = [
{ "id": "Z2-Black-TeeID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "T-Shirt [Black]"
},
{ "id": "Z2-White-TeeID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "T-Shirt [White]"
},
{ "id": "Z2-TrousersID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "Trousers"
},
{ "id": "Z2-SocksID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "Socks"
},
{ "id": "Z2-Red-TeeID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "T-Shirt [Red]"
},
]
const productSiblings = clothing.map(
(product, index) => ({
id: product.id,
title: product.title,
index,
siblings: [] // Ideally this would contain the IDs of every item in the
// array that had a matching string before any '[' character
})
)
console.log(productSiblings)
// Current Output
const currentOutput = [
{
"id": "Z2-Black-TeeID-02",
"title": "T-Shirt [Black]",
"index": 0,
"siblings": []
},
{
"id": "Z2-White-TeeID-02",
"title": "T-Shirt [White]",
"index": 1,
"siblings": []
},
{
"id": "Z2-TrousersID-02",
"title": "Trousers",
"index": 2,
"siblings": []
},
{
"id": "Z2-SocksID-02",
"title": "Socks",
"index": 3,
"siblings": []
},
{
"id": "Z2-Red-TeeID-02",
"title": "T-Shirt [Red]",
"index": 4,
"siblings": []
}
]
// Desired Output
const desiredOutput = [
{
"id": "Z2-Black-TeeID-02",
"title": "T-Shirt [Black]",
"index": 0,
"siblings": ["Z2-White-TeeID-02", "Z2-Red-TeeID-02"]
},
{
"id": "Z2-White-TeeID-02",
"title": "T-Shirt [White]",
"index": 1,
"siblings": ["Z2-Black-TeeID-02", "Z2-Red-TeeID-02"]
},
{
"id": "Z2-TrousersID-02",
"title": "Trousers",
"index": 2,
"siblings": []
},
{
"id": "Z2-SocksID-02",
"title": "Socks",
"index": 3,
"siblings": []
},
{
"id": "Z2-Red-TeeID-02",
"title": "T-Shirt [Red]",
"index": 4,
"siblings": ["Z2-Black-TeeID-02", "Z2-White-TeeID-02"]
}
]
Upvotes: 0
Views: 179
Reputation: 217
getSiblings
is iterating through clothing
and return an array of siblings
const clothing = [
{ "id": "Z2-Black-TeeID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "T-Shirt [Black]"
},
{ "id": "Z2-White-TeeID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "T-Shirt [White]"
},
{ "id": "Z2-TrousersID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "Trousers"
},
{ "id": "Z2-SocksID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "Socks"
},
{ "id": "Z2-Red-TeeID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "T-Shirt [Red]"
},
]
const getSiblings = (title) => {
const results = []
clothing.forEach(product => {
if (product.title !== title && product.title.includes(title.split('[')[0])) {
results.push(product.id);
}
})
return results;
}
const productSiblings = clothing.map(
(product, index) => ({
id: product.id,
title: product.title,
index,
siblings: getSiblings(product.title)
})
);
console.log(productSiblings)
Upvotes: 1
Reputation: 16576
Here's a solution that uses map
and filter
. Importantly, we use toLowerCase
and trim
to make sure our comparisons aren't too strict. Additionally, we make sure we don't say an item is a sibling of itself.
const clothing = [
{ "id": "Z2-Black-TeeID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "T-Shirt [Black]"
},
{ "id": "Z2-White-TeeID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "T-Shirt [White]"
},
{ "id": "Z2-TrousersID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "Trousers"
},
{ "id": "Z2-SocksID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "Socks"
},
{ "id": "Z2-Red-TeeID-02",
"availableForSale": true,
"createdAt": "2019-03-20T17:12:43Z",
"title": "T-Shirt [Red]"
},
]
const similarItems = (item1, item2) =>
item1.title.toLowerCase().split("[")[0].trim() ===
item2.title.toLowerCase().split("[")[0].trim();
const related = clothing.map(item => ({
...item,
siblings: clothing
.filter(el => el !== item && similarItems(el, item))
.map(el => el.id)
}))
console.log(related);
Upvotes: 2