I've been trying for 3 days straight to figure this out, by this point I don't even know what to search for.
I have an array of objects, I would like to get the greatest "bid_amount" for each "item_id", and then use the item_id, bid_amount and bidder_id in the DOM. I am stuck at the first step.
[
{
"item_id": "1",
"bid_amount": "765432",
"bidder_id": "298709"
},
{
"item_id": "1",
"bid_amount": "380",
"bidder_id": "606396"
},
{
"item_id": "2",
"bid_amount": "545",
"bidder_id": "606396"
},
{
"item_id": "2",
"bid_amount": "525",
"bidder_id": "317740"
},
{
"item_id": "2",
"bid_amount": "505",
"bidder_id": "606396"
},]
function getBids() {
var request = new XMLHttpRequest();
request.open('POST', '/get_bids.php', true);
request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
request.onload = function() {
bids = JSON.parse(this.response)
bids.reduce(function(prev, curr) {
currItemId = curr.item_id
currBidAmnt = curr.bid_amount
const item_id = (prev[curr.item_id] || []);
const prevBidsForId = prev[currItemId];
if (prevBidsForId) {
console.log(' a bid for this item exists, now i need to check if the current bid amount is greater than the previous bid amount for this item ')
item_id.push(curr)
prev[currItemId] = item_id
} else {
// push current item to prev
console.log(' a bid for this item does not exist ')
item_id.push(curr)
prev[currItemId] = item_id
}
return prev
}, [])
}
CodePudding user response:
You can simply 'group by' item_id
and simultaneously store the max bid in the grouped object. Here using a for...of
loop but you can shift the logic directly into a reduce
if you like. (This stores all the bids in an array keyed by item_id
and the max
bid is assigned to a seperate property.
const bids = [{ "item_id": "1", "bid_amount": "765432", "bidder_id": "298709" }, { "item_id": "1", "bid_amount": "380", "bidder_id": "606396" }, { "item_id": "2", "bid_amount": "545", "bidder_id": "606396" }, { "item_id": "2", "bid_amount": "525", "bidder_id": "317740" }, { "item_id": "2", "bid_amount": "505", "bidder_id": "606396" }];
const bidsById = {};
for (const bid of bids) {
(bidsById[bid.item_id] ??= { bids: [], max: bid }).bids.push(bid);
if (bid.bid_amount > bidsById[bid.item_id].max.bid_amount) {
bidsById[bid.item_id].max = bid;
}
}
for (const [id, { max }] of Object.entries(bidsById)) {
console.log(`${id}: ${max.bid_amount}`);
}
If you only want the bid_amount
in the result you can simplify
const bids = [{ "item_id": "1", "bid_amount": "765432", "bidder_id": "298709" }, { "item_id": "1", "bid_amount": "380", "bidder_id": "606396" }, { "item_id": "2", "bid_amount": "545", "bidder_id": "606396" }, { "item_id": "2", "bid_amount": "525", "bidder_id": "317740" }, { "item_id": "2", "bid_amount": "505", "bidder_id": "606396" }];
const bidsById = bids.reduce((a, { item_id, bid_amount }) => {
if (bid_amount > (a[item_id] ??= bid_amount)) {
a[item_id] = bid_amount;
}
return a;
}, {})
for (const [id, max] of Object.entries(bidsById)) {
console.log(`${id}: ${max}`);
}
CodePudding user response:
Here is a short .reduce()
based script that will filter out the object with the highest bid:
const bids=[
{
"item_id": "1",
"bid_amount": "765432",
"bidder_id": "298709"
},
{
"item_id": "1",
"bid_amount": "380",
"bidder_id": "606396"
},
{
"item_id": "2",
"bid_amount": "545",
"bidder_id": "606396"
},
{
"item_id": "2",
"bid_amount": "525",
"bidder_id": "317740"
},
{
"item_id": "2",
"bid_amount": "505",
"bidder_id": "606396"
}];
const highest = Object.values(bids.reduce((a,c)=>{
let aa=a[c.item_id];
if(!aa||c.bid_amount>aa.bid_amount) a[c.item_id]=c;
return a }, {}));
console.log(highest);