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]]));
Related
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]]));
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]]));
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.
jsfiddle with all the data which crashes and doesn't run.
jsfiddle with less data which runs but if you
console.log(`row ${g}, col ${i}`);
console.log(obj[pastWinners]);
It shows it is undefined.
I have a multi dimensional array in Javascript which runs some calculations for me. This array gets converted to a object literal and then after some data manipulation is changed to a json object and eventually a string. The program works great!
I have to add 310 more lines to the multi dimensional array. When I do I get this error,
index.html:331 Uncaught TypeError: Cannot read property '0' of
undefined
The original array looks like this,
var pastWinners = [
[2, 9, 19, 23, 38, 40],
[17, 25, 31, 35, 38, 43],
[8, 10, 17, 30, 33, 43],
[10, 17, 26, 28, 36, 43],
[14, 20, 25, 28, 34, 41],
[8, 13, 21, 23, 25, 43],
[10, 11, 18, 24, 27, 30],
[21, 22, 23, 26, 33, 39],
[6, 21, 23, 29, 36, 40],
[10, 12, 16, 21, 25, 42],
[1, 11, 20, 27, 34, 37]
];
Notice the single digit numbers do not have a 0 in the tens place. But the new data looks like this,
[05, 07, 17, 18, 33, 35],
It does have a 0 in the tens place. I mention this because from aside from it being 310 more lines to the array that is the only difference. I have checked the data 50 times and there is nothing wrong with it.
Would a small difference like that make a difference to cause an error like this? It says the error is getting throws at line 331 in my program,
var obj = {};
for (var g = 0; g < pastWinners.length; g++) {
for (var i = 0, j = pastWinners.length; i < j; i++) {
if (obj[pastWinners[g][i]] == undefined) {
console.log(`row ${g}, col ${i}`);
console.log(obj[pastWinners]);
}
if (obj[pastWinners[g][i]]) { //this is line 331
obj[pastWinners[g][i]]++;
} else {
obj[pastWinners[g][i]] = 1;
}
}
}
var picks = [];
for (var numbs in obj) {
picks.push([numbs, obj[numbs]])
picks.sort(
function(a, b) {
return a[1] - b[1]
}
)
}
picks.reverse();
var topPicks = []
for (var winners = 0; winners < 6; winners++) {
topPicks.push(picks[winners][0]);
}
var weekPicks = topPicks.toString();
console.log(weekPicks);
alert(weekPicks);
Does anyone see any reason this would happen when I add this data in? If it is an issue of the size of the array how can I handle this because I have a few thousand more lines of data to add in.
row 0, col 0
index.html:333 undefined
index.html:332 row 0, col 1
index.html:333 undefined
index.html:332 row 0, col 2
index.html:333 undefined
index.html:332 row 0, col 3
index.html:333 undefined
index.html:332 row 0, col 4
index.html:333 undefined
index.html:332 row 0, col 5
index.html:333 undefined
index.html:332 row 0, col 6
index.html:333 undefined
By adding a console.log(g) of what index you were up to when the error happens, this is actually an issue with your data:
[2, 7, 8, 9, 27, 38],
[9, 12, 17, 24, 26, 41]
[18, 20, 21, 31, 40, 44],
You are missing a comma after the 176th index. https://jsfiddle.net/6h7bedtL/1/
Try to print the array in the console when you get undefined and check your array size in the log.
for (var g = 0; g < pastWinners.length; g++) {
for (var i = 0, j = pastWinners.length; i < j; i++) {
if (obj[pastWinners[g][i]] == undefined){
console.log(`row ${g}, col ${i}`);
console.log(obj[pastWinners]);
}
if (obj[pastWinners[g][i]]) { //this is line 331
obj[pastWinners[g][i]]++;
} else {
obj[pastWinners[g][i]] = 1;
}
}
}
I would do it differently:
a. change the second loop...
b. define obj
var pastWinners = [
[2, 9, 19, 23, 38, 40],
[17, 25, 31, 35, 38, 43],
[8, 10, 17, 30, 33, 43],
[10, 17, 26, 28, 36, 43],
[14, 20, 25, 28, 34, 41],
[8, 13, 21, 23, 25, 43],
[10, 11, 18, 24, 27, 30],
[21, 22, 23, 26, 33, 39],
[6, 21, 23, 29, 36, 40],
[10, 12, 16, 21, 25, 42],
[1, 11, 20, 27, 34, 37],
];
var obj=[];
for (var g = 0; g < pastWinners.length; g++) {
for (var i = 0; i < pastWinners[g].length; i++) {
if (obj[pastWinners[g][i]]) { //this is line 331
obj[pastWinners[g][i]]++;
} else {
obj[pastWinners[g][i]] = 1;
}
}
}
console.log(obj)
Also you should check for the existence of pastWinners[g] before you loop through it or try to access a child array using
if (pastWinners[g] != null) {
The reason for this is that if pastWinners[g] for some reason is not defined, then your script will attempt to do this:
undefined[i] or get the value of [i] from undefined -- which it cant because undefined is not an array -- which breaks your script
var pastWinners = [
[2, 9, 19, 23, 38, 40],
[17, 25, 31, 35, 38, 43],
[8, 10, 17, 30, 33, 43],
[10, 17, 26, 28, 36, 43],
[14, 20, 25, 28, 34, 41],
[8, 13, 21, 23, 25, 43],
[10, 11, 18, 24, 27, 30],
[21, 22, 23, 26, 33, 39],
[6, 21, 23, 29, 36, 40],
[10, 12, 16, 21, 25, 42],
[1, 11, 20, 27, 34, 37],
];
for (var g = 0; g < pastWinners.length; g++) {
if (pastWinners[g] != null) { // check for valid item
for (var i = 0, j = pastWinners[g].length; i < j; i++) {
if (pastWinners[g][i] != null) {
pastWinners[g][i]++;
} else {
pastWinners[g][i] = 1;
}
}
}
}
console.log(pastWinners);
Possibly
for (var i = 0, j = pastWinners.length; i < j; i++)
should be
for (var i = 0, j = pastWinners[g].length; i < j; i++)
The array items in pastWinners do not have the length of pastwinners :D
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 ]