method sort not sorting last nested array JavaScript - javascript

somehow arr[i].sort() not sorting last nested array and i getting bad result.
tryed FOR and WHILE, different operators, nothing helped. what im doing wrong?
it have return biggest numbers in array.
function largestOfFour(arr) {
var i = 0;
while (i != arr.length) {
arr[i] = arr[i].sort().pop();
i++;
}
return arr;
}
largestOfFour([
[4, 5, 8, 1, 3],
[13, 27, 18, 26],
[32, 35, 37, 39],
[1000, 1001, 817, 1]
]);

By default sort() orders the elements as strings, not numbers, and "1001" < "817". If you want a numeric sort you need to provide a comparison function that performs numeric ordering.
function largestOfFour(arr) {
var i = 0;
while (i != arr.length) {
arr[i] = arr[i].sort(function(a, b) {
return a - b;
}).pop();
i++;
}
return arr;
}
console.log(largestOfFour([
[4, 5, 8, 1, 3],
[13, 27, 18, 26],
[32, 35, 37, 39],
[1000, 1001, 817, 1]
]));

Not the cause of the problem you are seeing (which #Barmar answered), but you can use Array.map with Math.max.apply to get the max number of each list:
function largestOfFour(arr) {
return arr.map(function(list) {
return Math.max.apply(null, list);
});
}
console.log(largestOfFour([
[4, 5, 8, 1, 3],
[13, 27, 18, 26],
[32, 35, 37, 39],
[1000, 1001, 817, 1]
]));
Or a bit more concise with ES6:
const largestOfFour = arr => arr.map(list => Math.max(...list))

The problem is in sort defaults - it sorts the array as strings - so "8..." > "1..."
Try following:
function cmp(a,b){
return a-b;
}
function largestOfFour(arr) {
var i = 0;
while (i != arr.length) {
arr[i] = arr[i].sort(cmp).pop();
i++;
}
return arr;
}
largestOfFour([
[4, 5, 8, 1, 3],
[13, 27, 18, 26],
[32, 35, 37, 39],
[1000, 1001, 817, 1]
]);
Output: [ 8, 27, 39, 1001 ]

Related

Javascript function returning 'undefined'

I've written a a function which takes score as parameter and should return the letter grade.
There are some conditions to be followed while writing the code. ie: return 'A' if 25 < score <= 30 return 'B' if 20 < score <= 25 and so on. So I wanted to do this by omitting a whole lot of if-else's. As I'm new to javascript this is all I could come up with:
// This function takes Nested arrays and a single number,
// which checks its availability in
// the inside array and then return the index of the array
function my_index(arr, score) {
for (const [index, elem] of arr.entries()) {
if (elem.includes(score)) {
return index;
}
}
}
// function to get letter grade
function getGrade(score) {
let grade;
var gradeDict = {
'A': [26, 27, 28, 29, 30],
'B': [21, 22, 23, 24, 25],
'C': [16, 17, 18, 19, 20],
'D': [11, 12, 13, 14, 15],
'E': [6, 7, 8, 9, 10],
'F': [0, 1, 2, 3, 4, 5]
}
var keys = Object.keys(gradeDict);
var values = [Object.values(gradeDict)]
grade = keys[my_index(values, score)]
return grade;
}
The first function works fine. It returns the index of nested array. But the main function getGrade happens to return 'Undefined'. Can't think of a better solution than this to reduce a bunch of ugly if-elses.
var question = {
'1st': 'Can anybody help me get this done?',
'2nd': 'Is there any better way to do this?'
}
Is there a better way to write this?
I'd do:
function getLetterGrade(score) {
return ['F', 'F', 'E', 'D', 'C', 'B', 'A'][Math.ceil(score / 5)];
}
(F occurs twice because more scores map to F than to other grades)
It may be a bit cryptic, but is easier to tune should the possible score ever change.
Remove the outer [] array of the Object.values. Object.values already returns values in array.
from
var values = [Object.values(gradeDict)];
to
var values = Object.values(gradeDict);
working example:
function my_index(arr, score) {
for (const [index, elem] of arr.entries()) {
if (elem.includes(score)) {
return index;
}
}
}
function getGrade(score) {
let grade;
var gradeDict = {
A: [26, 27, 28, 29, 30],
B: [21, 22, 23, 24, 25],
C: [16, 17, 18, 19, 20],
D: [11, 12, 13, 14, 15],
E: [6, 7, 8, 9, 10],
F: [0, 1, 2, 3, 4, 5],
};
var keys = Object.keys(gradeDict);
var values = Object.values(gradeDict);
grade = keys[my_index(values, score)];
return grade;
}
console.log(getGrade(5));
console.log(getGrade(25));
Alternate solution
function getGrade(score) {
let grade;
var gradeDict = {
A: [26, 27, 28, 29, 30],
B: [21, 22, 23, 24, 25],
C: [16, 17, 18, 19, 20],
D: [11, 12, 13, 14, 15],
E: [6, 7, 8, 9, 10],
F: [0, 1, 2, 3, 4, 5],
};
for (let key in gradeDict) {
if (gradeDict[key].includes(score)) return key;
}
return "Not found";
}
console.log(getGrade(5));
console.log(getGrade(25));
I like the ceil solution proposed earlier, but here is another general solution in case it's helpful:
function grade(score) {
if (score < 0 || score > 30) throw RangeError(`Score ${score} out of range`);
for (let ii = 5; ii >= 0; ii--) {
if (score > 5*ii) return String.fromCharCode(70 - ii);
}
return 'F';
}
console.log(0, '=>', grade(0)) // F
console.log(4, '=>', grade(4)) // F
console.log(6, '=>', grade(6)) // E
console.log(10, '=>', grade(10)) // E
console.log(27, '=>', grade(27)) // A
console.log(30, '=>', grade(30)) // A

How do I pass this algorithm challenge?

I am working through freecodecamp's basic algorithm challenges. The challenge is to return the largest number in an array. Here's the code.
function largestOfFour(arr) {
// You can do this!
let largestWord = [0,0,0,0];
for(let i = 0; i < arr.length; i++) {
for(let j = 0; j < arr[i].length; j++) {
if(arr[i][j] > largestWord[i]) {
largestWord[i] = arr[i][j];
}
}
}
return largestWord;
}
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);
I have passed three of the criteria:
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]) should return an array.
Passed
largestOfFour([[13, 27, 18, 26], [4, 5, 1, 3], [32, 35, 37, 39], [1000, 1001, 857, 1]]) should return [27, 5, 39, 1001].
Passed
largestOfFour([[4, 9, 1, 3], [13, 35, 18, 26], [32, 35, 97, 39], [1000000, 1001, 857, 1]]) should return [9, 35, 97, 1000000].
All except largestOfFour([[17, 23, 25, 12], [25, 7, 34, 48], [4, -10, 18, 21], [-72, -3, -17, -10]]) should return [25, 48, 21, -3].
Where did I go wrong?
So in your code you went wrong in this block.
if(arr[i][j] > largestWord[i]) {
largestWord[i] = arr[i][j];
}
The thing you forgot was you have a starting value for the largest number which is 0 and you compare array elements with that value. Only a value exceeds 0 going to replace that. So I would suggest just to initialize the array without values and do a check for that
//initialize the array without a value
let largestWord = new Array(4);
for(let i = 0; i < arr.length; i++) {
for(let j = 0; j < arr[i].length; j++) {
//also add a check for initial value
if(arr[i][j] > largestWord[i] || largestWord[i] == undefined) {
largestWord[i] = arr[i][j];
}
}
}
Seems you can do this a lot easier with .map() and Math.max()
function largestOfFour(arr) {
return arr.map(x => Math.max(...x));
}
console.log(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]));
console.log(largestOfFour([[17, 23, 25, 12], [25, 7, 34, 48], [4, -10, 18, 21], [-72, -3, -17, -10]]));

Trouble using Math.max() in a For loop

I want to get the biggest number on each array looping [0,1,2,3] with for.
I am not managing to figure what to do in order to have the desired output.
function largestOfFour(arr) {
for (let i = 0; i < arr.length; i++){
console.log(Math.max(...arr[i])) \\returns => 5, 27, 39, 1001
}
}
console.log(largestOfFour([[4, 5, 1], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]));
console.log(Math.max(...arr[i])) returns 5, 27, 39, 1001. When I remove console.log and use a return at this line, in many different approaches, the iteration is not done. The loop stops and returns just the biggest number at arr[0] instead of looping completely.
The desired output is to get the biggest number of each array = 5, 27, 39, 1001
you can't return more than once from a function
Your code, if it returned in the body of the for loop, would return from the function in the first iteration
use Array map function
function largestOfFour(arr) {
return arr.map(a => Math.max(...a))
}
console.log(largestOfFour([[4, 5, 1], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]));
function largestOfFour(arr) {
let result = [];
for (let i = 0; i < arr.length; i++){
result.push(Math.max(...arr[i]));
}
return result;
}
console.log(largestOfFour([[4, 5, 1], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]));

Javascript looping through arrays of arrays

So I've been fighting with this a few hours now- the goal is to create a new array of the highest numbers in each array of 4. However, I can't seem to get it to loop more than once. How am I screwing up this for loop?
function largestOfFour(arr) {
for (var i = 0; i < arr.length; i++) {
var allTop = "";
var top = arr[i].sort(function(a, b) {
return b - a;
});
i++;
allTop.push(top[0]);
}
}
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);
The variable allTop should be defined before the loop as an array, and returned after the loop ends:
function largestOfFour(arr) {
var allTop = [];
for (var i = 0; i < arr.length; i++) {
var top = arr[i].sort(function(a, b) {
return b - a;
});
allTop.push(top[0]);
}
return allTop;
}
console.log(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]));
A better approach is using the function map along with the function Math.max
function largestOfFour(arr) {
return arr.map(function(a) {
return Math.max.apply(null, a);
});
}
var result = largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);
console.log(result);
Full ES6:
var largestOfFour = (arr) => arr.map(a => Math.max(...a));
var result = largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);
console.log(result);
Try this:
function largestOfFour(arr) {
let allTop = [];
arr.forEach(a => {
allTop.push(Math.max.apply(Math, a));
});
return allTop;
}
console.log(
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]])
);
Other solution would be to use function reduce along with the function Math.max
function largestOfFour(arr) {
return arr.reduce((a, x) => {
a.push(Math.max.apply(null,x));
return a;
}, []);
}
console.log(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]));

i wanted to make arr[0][0] appear largest to smallest but while running it shows the type error arr[i].sort(); is not a function

function largestOfFour(arr) {
var largestNumArray = [];
for(i = 0; i < arr.length; i++) {
arr = arr[i].sort(function(a, b) {
return b - a;
});
}
}
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);
Where am I wrong and could you explain about it.
while running it shows the type error arr[i].sort(); is not a
function.
You are mutating the arr by assigning the result of arr[i].sort() to arr
Make it
arr[i]=arr[i].sort(function(a,b){
return b-a;
});
Edit
sort function mutates the array by itself, so no reason to store it back to arr[i] anyways.
arr[i].sort(function(a,b){
return b-a;
});
Here's a non-mutating version:
const largestOfFour = arr => arr.map(four => four.slice(0).sort((a, b) => a - b))
const foo = [[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]
largestOfFour(foo);
//=> [[4, 5, 1, 3], [13, 18, 26, 27], [32, 35, 37, 39], [1, 857, 1000, 1001]]
// but foo is unchanged
Using map together with slice(0), we can avoid mutation.

Categories

Resources