-1

I have a single 1d array storing a series of scores. My end goal is to have the 5 highest scores with brackets around them ( e.g. (score) ) for me to then format and output onto the display. In the case where there are duplicate scores, the first occurrences would be bracketed, up to that 5 top values.

So for example: [9,8,10,9,6,8,6,5,4,4,3,3,6] would become [(9),(8),(10),(9),6,(8),6,5,4,4,8,3,8]

What I've tried so far is this:

var topvals = scores.sort((a,b) => b-a).slice(0,5);
    for(var j=0; j< scores.length; j++){
      if(topvals.length==0){
        break;
      }else if(topvals.includes(scores[j])){
        scores[j] = "(" + scores[j] + ")";
        topvals.splice(topvals.indexOf(scores[j]),1);
      }
    }

With the idea that topvals is an array containing the top 5 values, and I then loop through scores looking for those values, removing them each time.

What this results in is the first 5 values of scores having brackets around them.

I'm happy to go a completely different route with this, or just fix what I've done so far. Thanks in advance.

8
  • just clone scores. scoreclone = scores.slice() Commented Jun 22, 2020 at 15:25
  • Does this answer your question? Keep original array after JavaScript function Commented Jun 22, 2020 at 15:26
  • Unfortunately not. That post only deals with editing the array where you know where the values are. The problem I have is what is described in the text of the post. Commented Jun 22, 2020 at 20:12
  • Should dvals in your example be topvals? Also can you explain what error / unexpected behavior you are having? Commented Jun 22, 2020 at 20:24
  • How efficient does this need to be? Easiest way is to just scores.map((n,i)=>({n,i})).sort((a,b)=>b.n-a.n).slice(0,5).map(({i})=>i).forEach(i=>scores[i]=`(${scores[i]})`). If you need O(N) for large data sets, you can do a pivot algorithm. Commented Jun 22, 2020 at 20:25

2 Answers 2

0

sort with indexes attached. Use index positions to change to desired format. O(N log N) for the sort.

scores = [9,8,10,9,6,8,6,5,4,4,3,3,6]
scores.map((n,i)=>({n,i})) // each object as n: number, i: index
  .sort((a,b)=>a.n-b.n).slice(-5) // sort, slice top 5
  .forEach(({i})=>scores[i]=`(${scores[i]})`) // add parens by indexes

console.log(scores)

If you have very, very large data sets and need something closer to O(N), you'll want to implement a pivot selecting algorithm. Just sorting is simpler.

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

1 Comment

Thank you, sorting with indexes attached should work for this exactly. I had been bashing my head against the wall in one particular direction for a while so couldn't see other routes to take!
0

The call to sort() sorts scores in place, which means it changes the scores array. So that is why you need to clone it first, then sort, then slice. Also you probably want to eliminate duplicates from your scores. I linked a stack overflow answer that describes how to do that. Since filter does not filter scores in place, but rather returns a new array, you don't need to explicitly call slice(0) to clone scores.

var scores = [9,8,10,9,6,8,6,5,4,4,3,3,6];

// Function from linked SO answer.
function onlyUnique(value, index, self) { 
    return self.indexOf(value) === index;
}

// Filter unique scores into copy of array, then slice the top 5.
var topvals = scores.filter(onlyUnique).sort((a,b) => b-a).slice(0,5);

for (var j=0; j< scores.length; j++) {
   if( topvals.length==0) {
        break;
   } else if(topvals.includes(scores[j])) {
        scores[j] = "(" + scores[j] + ")";
        topvals.splice(topvals.indexOf(scores[j]),1);
   }
}

Get all unique values in a JavaScript array (remove duplicates)

1 Comment

The problem with this is that I need to keep the duplicates. The question stems from the very end of a bigger project where I just need to do some formatting before output so the data needs to be kept exactly as is.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.