Home > Software engineering >  Process array of objects to return least priced per product using JavaScript
Process array of objects to return least priced per product using JavaScript

Time:09-05

Given an array of objects, containing products. A single object contains a single product offer. Products can have a identical productId, while offerId are unique for each product.

Process the data to get the cheapest priced item for each offer

const data = [
    { productId: 'dhdiwu', offerId: 'd3en', price: '$12.20' },
    { productId: 'dhdiwu', offerId: 's2dr', price: '$8.45' },
    { productId: 'dhdiwu', offerId: 'hy38', price: '$21.21' },
    { productId: 'dowksm', offerId: 'ie8u', price: '$1.77' },
    { productId: 'dowksm', offerId: 'djs3', price: '$24.21' },
    { productId: 'dowksm', offerId: 'pies', price: '$92.36' },
    { productId: 'bdbhsu', offerId: '9wid', price: '$100.98' }
]
const dataArray = data.reduce((prev, t, index, arr) => {
    if (typeof prev[t.productId] === 'undefined') {
      prev[t.productId] = [];
    }
    prev[t.productId].push(t);
    return prev;
  }, {});
  let same_id  = [] 
  let cheapest = []
  Object.keys(dataArray).forEach(i => {
    same_id.push(dataArray[i]);
});

console.log(same_id)

//output for now
/*[
    [
      { productId: 'dhdiwu', offerId: 'd3en', price: '$12.20' },
      { productId: 'dhdiwu', offerId: 's2dr', price: '$8.45' },
      { productId: 'dhdiwu', offerId: 'hy38', price: '$21.21' }
    ],
    [
      { productId: 'dowksm', offerId: 'ie8u', price: '$1.77' },
      { productId: 'dowksm', offerId: 'djs3', price: '$24.21' },
      { productId: 'dowksm', offerId: 'pies', price: '$92.36' }
    ],
    [ { productId: 'bdbhsu', offerId: '9wid', price: '$100.98' } ]
]*/

CodePudding user response:

I would first start by grouping the products by productId, something like what is suggested here should work: Most efficient method to groupby on an array of objects

function groupByKey(array, key) {
const groupedObject = {}
for (const item of array) {
  const value = item[key]
    if (groupedObject[value] === undefined) {
  groupedObject[value] = []
  }
  groupedObject[value].push(item)
}
  return groupedObject
}

groupByKey(data, 'productId')

Now you have an object with three properties, the unique productID's with each product inside it. Then loop through each one, find the lowest price.

const grouped = groupByKey(data, 'productId');
const lowest = {};
for (const group of Object.keys(grouped)) {
    if (!lowest[group]) {
        lowest[group] = '';
    }
  for (const product of grouped[group]) {
      if (lowest[group] === '') {
        lowest[group] = product.price
      }
    if (product.price < lowest[group]) {
        lowest[group] = product.price;
    }
  }
}
console.log(lowest);
// {dhdiwu: '$12.20', dowksm: '$1.77', bdbhsu: '$100.98'}

It's a little scrappy, and I'm sure there are some cool one-liners you could build, but that's the general idea.

CodePudding user response:

If I understand correctly, you're looking to find the lowest priced offer for each productId.

You can go with this:

const data = [
  { productId: 'dhdiwu', offerId: 'd3en', price: '$12.20' },
  { productId: 'dhdiwu', offerId: 's2dr', price: '$8.45' },
  { productId: 'dhdiwu', offerId: 'hy38', price: '$21.21' },
  { productId: 'dowksm', offerId: 'ie8u', price: '$1.77' },
  { productId: 'dowksm', offerId: 'djs3', price: '$24.21' },
  { productId: 'dowksm', offerId: 'pies', price: '$92.36' },
  { productId: 'bdbhsu', offerId: '9wid', price: '$100.98' }
]

// group by productId and find the lowest price
const result = data.reduce((acc, { productId, offerId, price }) => {
  const current = acc[productId]
  if (!current || current.price > price) {
    acc[productId] = { offerId, price }
  }
  return acc
}, {})

console.log(result)

output:

node .\scratch.js
{
  dhdiwu: { offerId: 'd3en', price: '$12.20' },
  dowksm: { offerId: 'ie8u', price: '$1.77' },
  bdbhsu: { offerId: '9wid', price: '$100.98' }
}
  • Related