Reputation: 27
In the code below, I use "push" to fill and empty array. I need help to write the above code so that it comes out the same way, without using "push". I have been challenged to this by the book, "Head First JavaScript Programming". I have tried, but I am stumped.
let scores = [60, 50, 60, 58, 54, 54, 58, 50, 52, 54, 48, 69, 34, 55, 51, 52, 44, 51, 69,
64, 66, 55, 52, 61, 46, 31, 57, 52, 44, 18, 41, 53, 55, 61, 51, 44
]
var highScore = 0
var output
for (var i = 0; i < scores.length; i++) {
output = `Bubbles solution # ${i} score: ${scores[i]}<br>`
document.write(output)
if (scores[i] > highScore) {
highScore = scores[i]
}
}
let bestSolutions = []
for (var i = 0; i < scores.length; i++) {
if (scores[i] == highScore) {
bestSolutions.push([i])
}
}
document.write(`Bubbles Tests: ${scores.length}<br>`)
document.write(`Highest Bubble Score: ${highScore}<br>`)
document.write(`Solutions with highest score: #${bestSolutions[0]} and #${bestSolutions[1]}`)
Upvotes: 1
Views: 2081
Reputation: 76551
A very obvious alternative would be
bestSolutions[bestSolutions.length] = [i];
Explanation: At any time, in bestSolutions
you have exactly bestSolutions.length
number of elements. The first has the index of 0, the second has the index of 1, ..., the last is having the index of bestSolutions.length - 1
. Hence, the index of the n+1th element will be bestSolutions.length
. After assigning the new value to this index, bestSolutions.length
will equal its former value + 1.
The edge-case in the above is when bestSolutions
is empty, in which case it does not have first or last elements, but the suggested code will work for this case as well, because in this case bestSolutions.length
will be 0, exactly the element you want to initialize.
let scores = [60, 50, 60, 58, 54, 54, 58, 50, 52, 54, 48, 69, 34, 55, 51, 52, 44, 51, 69,
64, 66, 55, 52, 61, 46, 31, 57, 52, 44, 18, 41, 53, 55, 61, 51, 44
]
var highScore = 0
var output
for (var i = 0; i < scores.length; i++) {
output = `Bubbles solution # ${i} score: ${scores[i]}<br>`
document.write(output)
if (scores[i] > highScore) {
highScore = scores[i]
}
}
let bestSolutions = []
for (var i = 0; i < scores.length; i++) {
if (scores[i] == highScore) {
bestSolutions[bestSolutions.length] = [i];
}
}
document.write(`Bubbles Tests: ${scores.length}<br>`)
document.write(`Highest Bubble Score: ${highScore}<br>`)
document.write(`Solutions with highest score: #${bestSolutions[0]} and #${bestSolutions[1]}`)
Upvotes: 0
Reputation: 1
You can use ( ) rather than [ ] in bestSolutions.push(i)
var bestSolutions = [];
for (let i = 0; i < scores.length; i++) {
if (scores[i] == highScore) {
bestSolutions.push(i)
}
}
Upvotes: 0
Reputation: 41
Ok, one approach is the following : If you want your bestscores
array to contain the indices of the elements in scores
that are equal to highscore
, you can define bestcores
as the map of scores
through the function that takes a tuple (value,index)
and return index
if value == highscore
otherwise null
.
const a = [2, 3, 5, 0, 6];
const b = a.map(value => value * 2); // [4, 6, 10, 0, 12];
const c = a.map((value, index) => index); //[0, 1, 2, 3, 4];
const d = a.map((value, index) => value + index); //[2, 4, 7, 3, 10];
const e = a.map((value,index) => value >= 3 ? index : null);
// [null, 1, 2, null, 4]. We can deal with those nulls with a filter
const f = e.filter(value => value != null) // [1,2,4]
const highscores = scores.map((value,index) => value == highscore ? index : null)
.filter(value => value != null);
This gives you a high level approach but is a bit computationally inefficient as it actually does a double iteration over the scores
array. A manual iteration over your array and a push
is actually more efficient.
Upvotes: 0
Reputation: 24925
You can try this approach:
Math.max.apply
to find the highest score.let scores = [ 60, 50, 60, 58, 54, 54, 58, 50, 52, 54, 48, 69, 34, 55, 51, 52, 44, 51, 69, 64, 66, 55, 52, 61, 46, 31, 57, 52, 44, 18, 41, 53, 55, 61, 51, 44 ]
var highScore = Math.max.apply(null, scores)
var bestSolutions = scores.reduce((acc, score, index) =>
score === highScore ? [ ...acc, index] : acc, []
);
document.write(`Bubbles Tests: ${scores.length}<br>`)
document.write(`Highest Bubble Score: ${highScore}<br>`)
document.write(`Solutions with highest score: #${bestSolutions[0]} and #${bestSolutions[1]}`)
Algo based:
Create 2 variables, highScore
and bestSolutions
.
Loop over Array.
For every iteration, make 2 checks:
If current score
is greater than highScore
highScore
with current score and initialize bestSolutions
with current index.If highScore
is equal to current score
bestSolutions
let scores = [ 60, 50, 60, 58, 54, 54, 58, 50, 52, 54, 48, 69, 34, 55, 51, 52, 44, 51, 69, 64, 66, 55, 52, 61, 46, 31, 57, 52, 44, 18, 41, 53, 55, 61, 51, 44 ];
let highScore = 0;
let bestSolutions = [];
for(let i = 0; i< scores.length; i++) {
if (scores[i] > highScore) {
highScore = scores[i];
bestSolutions = [ i ];
} else if (scores[i] === highScore) {
bestSolutions.push(i)
}
}
document.write(`Bubbles Tests: ${scores.length}<br>`)
document.write(`Highest Bubble Score: ${highScore}<br>`)
document.write(`Solutions with highest score: #${bestSolutions[0]} and #${bestSolutions[1]}`)
Upvotes: 0
Reputation: 3504
If I understand this correctly you're looking to find all max values in an array of numbers. If that is the case, you can use the reduce
and filter
methods as an alternative to using push
.
function findMaxes(arr) {
const max = Math.max.apply(null, arr);
return arr.filter(n => n == max);
}
For example:
findMaxes([3, 5, 1, 1, 4, 5]) == [5, 5]
findMaxes([-1, -1, -1]) == [-1, -1, -1]
If you want to find the positions of all maxes:
function findAllMaxPositions(arr) {
const max = Math.max.apply(null, arr);
return arr.map((e, index) => [e, index])
.filter(pair => pair[0] == max)
.map(e => e[1]);
}
Upvotes: 1