简体   繁体   中英

Find nearest match of objects in JavaScript array

I have an array of non-sorted objects:

const participants = [
    {code: '222222', is_winner: true},
    {code: '444444', is_winner: false},
    {code: '777777', is_winner: false},
    {code: '555555', is_winner: true},
    {code: '666666', is_winner: false},
    {code: '111111', is_winner: false},
    {code: '333333', is_winner: false},
];

How do I find the nearest object, which is_winner key is true, given a participant, which is_winner key is always false.

if participant = {code: '333333', is_winner: false} 
=> 
Should return {code: '555555', is_winner: true}

if participant = {code: '444444', is_winner: false} 
=> 
Should return {code: '222222', is_winner: true}

I'm looking to get a participant that has won(is_winner is true) that is the closest to a non-winner participant. The array is noncircular.

Here is my answer from the information in your question

 const participants = [ {code: '222222', is_winner: true}, {code: '444444', is_winner: false}, {code: '777777', is_winner: false}, {code: '555555', is_winner: true}, {code: '666666', is_winner: false}, {code: '111111', is_winner: false}, {code: '333333', is_winner: false}, ]; function findClosestWinner(code, participants) { let index = participants.findIndex((participant) => { return participant.code === code }) let winner let awayDown = 0 let awayUp = 0 for (let x = index-1; x >= 0; x--) { let currentParticipant = participants[x] awayDown += 1 if (currentParticipant.is_winner) { winner = currentParticipant break } } for (let x = index+1; x < participants.length; x++) { let currentParticipant = participants[x] awayUp += 1 if (currentParticipant.is_winner && awayUp <= awayDown) { winner = currentParticipant break } } return winner } let winner = findClosestWinner('777777', participants) console.log(winner)
findClosestWinner takes a participant's code and the list of participants and returns the closest winning participant.

hopefully, this helps.

You can do it in one loop. Added comments but the principal is simple, loop through while watching out for a winner and storing it until you find the matching code. Once you found the code you are searching for find an upper winner. If found then find the closest one.

There might be some edge cases around the match being a winner, but since you didn't address those in your example problems I am going to pretend like they don't exist and let you program for them ;)

 let findCloseWinner = (code, participants) => { var low=-1, codeIx=-1; for(var i=0;i<participants.length;i++) { if(participants[i].code === code) codeIx = i; if(participants[i].is_winner) { // if we havent found our code then we have a new lower bound if(codeIx === -1) { low = i; } else { // find closer, is it lower or upper if(low === -1 || codeIx-low > i-codeIx) { return participants[i]; } else { return participants[low]; } } } } // If no code was found or we never found a lower bound then were done if(codeIx === -1 || low === -1) return null // no upper bound found during loop, low must be winner return participants[low]; } var participants = [ {code: '222222', is_winner: true}, {code: '444444', is_winner: false}, {code: '777777', is_winner: false}, {code: '555555', is_winner: true}, {code: '666666', is_winner: false}, {code: '111111', is_winner: false}, {code: '333333', is_winner: false}, ]; console.log(findCloseWinner('333333', participants)); console.log(findCloseWinner('444444', participants));

This can simply be:

 const data = [ {code: '222222', is_winner: true}, {code: '444444', is_winner: false}, {code: '777777', is_winner: false}, {code: '555555', is_winner: true}, {code: '666666', is_winner: false}, {code: '111111', is_winner: false}, {code: '333333', is_winner: false}, ]; let fn = (c, arr) => { let i = arr.findIndex(x => x.code === c) return data.slice(0, i).reverse().find(x => x.is_winner) } console.log(fn('333333', data)) // 555555 console.log(fn('444444', data)) // 222222

The idea is to get the index of the item with the provided code after which to slice the main array so you only have the items up to that index. Then simply reverse the result and get the first match on is_winner .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM