cal
cal

Reputation: 1863

Checking for matching strings in a .map() method

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

Answers (2)

Loc Mai
Loc Mai

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

Nick
Nick

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

Related Questions