0

I want to add a field inside each presentsData object called sumP and fill it with the presents item sum.

Second goal, if sumP > money I would like to delete the most expensive item inside It's not working

const presentsData= [
        {
          name: "Peter",
          presents: ["coffee","holidays"],
          money: 7000
        },
        {
          name: "Mario",
          presents: ["car","coal"],
          money: 300
        },
        {
          name: "Amanda",
          presents: ["computer","coal"],
          money: 300
        },
        {
          name: "David",
          presents: ["clothes", "car"],
          money: 2000
        }
    ]
    const prices= [
        {
          present: "coffee",
          price: 1
        },
        {
          present: "holidays",
          price: 1000
        },
        {
          present: "videogames",
          price: 40
        },
        {
          present: "computer",
          price: 600
        },
        {
          present: "tattoo",
          price: 30
        },
        {
          present: "clothes",
          price: 80
        },
        {
          present: "car",
          price: 6000
        },
        {
          present: "phone",
          price: 800
        },
        {
          present: "motorbike",
          price: 3500
        },
         {
          present: "coal",
          price: 0
        }
      ]
    
    const pricesMap = new Map(prices.map(({ present, price }) => [present, price]))
    
    const res1 =  presentsData.map(s=>{
    return {...s,
           sumP: s.presents.reduce((acc, p) => acc + pricesMap.get(p),0)
           }
    })
    
     console.log("this is res1=>",res1) //this is presentsData result after adding the field sumP
    
    console.log(pricesMap)
    
    const res2 = res1.map((r)=>{
      if(r.sumP > r.money){
      ( /* would like to delete the item  inside "presents" with the bigger price using pricesMap */)
      }
    })
    
    console.log(res2)

pd: what I find hard is to find out how to iterate in presents , array inside object inside array.

1
  • 1
    "Second goal, if sumP > money I would like to delete the most expensive item inside It's not working" what if sumP > money still holds true after deleting most expensive item, do we have to keep doing it until sumP <= money? Commented Jan 10, 2021 at 19:50

3 Answers 3

1

You can filter the presents and keep removing the most expensive presents until there's money to buy them:

const presentsData = [{
    name: "Peter",
    presents: ["coffee", "holidays"],
    money: 7000
  },
  {
    name: "Mario",
    presents: ["car", "coal"],
    money: 300
  },
  {
    name: "Amanda",
    presents: ["computer", "coal"],
    money: 300
  },
  {
    name: "David",
    presents: ["clothes", "car"],
    money: 2000
  }
]
const prices = [{
    present: "coffee",
    price: 1
  },
  {
    present: "holidays",
    price: 1000
  },
  {
    present: "videogames",
    price: 40
  },
  {
    present: "computer",
    price: 600
  },
  {
    present: "tattoo",
    price: 30
  },
  {
    present: "clothes",
    price: 80
  },
  {
    present: "car",
    price: 6000
  },
  {
    present: "phone",
    price: 800
  },
  {
    present: "motorbike",
    price: 3500
  },
  {
    present: "coal",
    price: 0
  }
]

const pricesMap = new Map(prices.map(({
  present,
  price
}) => [present, price]))

const withSumP = presentsData.map(s => {
  return { ...s,
    sumP: s.presents.reduce((acc, p) => acc + pricesMap.get(p), 0)
  }
})

console.log(withSumP) //this is presentsData result after adding the field sumP

const mostExpensive = (arr) => {
  return arr.reduce((acc, el) => {
    if (pricesMap.get(el) > pricesMap.get(acc)) {
      return el
    }
    return acc;
  })
}

// If you want to remove the most expensive present once for each element
const result = withSumP.map((el) => {
  if (el.sumP > el.money) {
    const presentToDelete = mostExpensive(el.presents);
    return { ...el,
      presents: el.presents.filter(p => p !== presentToDelete)
    }

  }
  return el;
})

console.log(result);

// If you want to delete presents until you can buy them and also update sumP to be in sync with the presents:

const resultAlt = withSumP.map((el) => {
  let updatedPresents = [...el.presents];
  let updatedSumP = el.sumP;
  while ((updatedSumP > el.money) && (updatedPresents.length > 0)) {
    const presentToDelete = mostExpensive(updatedPresents);
    updatedPresents = updatedPresents.filter(p => p !== presentToDelete);
    updatedSumP -= pricesMap.get(presentToDelete);
  }
  return { ...el,
    presents: updatedPresents,
    sumP: updatedSumP
  };
})

console.log(resultAlt)

Sign up to request clarification or add additional context in comments.

1 Comment

you are a genius, thank you very much. @Ramesh
1
const deleteMostExpensive = (array, prices) => {
    let res = [];
    let mostEspensive = array[0];
    array.forEach(product => {
        let cur = prices.find(p => p.present == product)
        if (cur.price > mostEspensive.price)
            mostEspensive = cur;
    })

    array.forEach(e => {
        if (e != mostEspensive.present)
            res.push(e);
    })

    return res;
}


const calculSumP = (elt, prices) => {
    r = 0;
    elt.presents.forEach(e => {
        r += prices.find(c => c.present == e).price;
    })
    return r;
}


presentsData.forEach(elt => {
    elt.sumP = calculSumP(elt, prices);

   while (elt.sumP > elt.money) {
       let newPresents = deleteMostExpensive(elt.presents, prices);
       elt.presents = newPresents;
       elt.sumP = calculSumP(elt, prices)
   }
})

Comments

1

This would be all that's required:

const items = (prices) => {
  let obj = {};
  for (p of prices) {
    obj[p.present] = p.price;
  }
  return obj;
}

var priceList = items(prices);

presentsData.forEach( (person) => {
 let presents = person.presents;
 person.sumP = presents.reduce( (acc, current) => {
   return acc + priceList[current];
 }, 0);
 if (person.sumP > person.money) {
   presents.sort( (a,b) => priceList[a] - priceList[b]);
   presents.pop();
 }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.