How to fix TypeError: Cannot read property 'length' of undefined in JavaScript? - javascript

I am trying to solve a very easy challenge about finding the longest word in a string.
This is the code:
function find(par) {
let arrayWord = par.split(" ");
let longestWord = "";
for (let i = 0; i <= arrayWord.length; i++) {
if (longestWord.length < arrayWord[i].length) {
longestWord = arrayWord[i]
}
}
return longestWord;
}
find("Find the longest word");
I would need help understanding why I am getting this error:
Uncaught TypeError: Cannot read property 'length' of undefined
at find (:5:47)
at :11:1 find # VM959:5 (anonymous) # VM959:11
thank you.

Cannot read property 'length' of undefined comes when it is not able to find variable of certain type(In your case a string) to call the function length. In your case arrayWord[i].length is not a proper string for the last condition of your check as there is no element arrayWord[arrayWord.length] present in the array. That's why arrayWord[i].length is giving you an error for your last iteration. Just change i <= arrayWord.length to i < arrayWord.length
function find(par) {
let arrayWord = par.split(" ");
let longestWord = "";
for (let i = 0; i <arrayWord.length; i++) {
if (longestWord.length < arrayWord[i].length) {
longestWord = arrayWord[i]
}
}
return longestWord;
}
Edits: Changes made as suggested by RobG

Just change condition <= to < and try
function find(par) {
let arrayWord = par.split(" ");
let longestWord = "";
for (let i = 0; i < arrayWord.length; i++) {
if (longestWord.length < arrayWord[i].length) {
longestWord = arrayWord[i]
}
}
return longestWord;
}
console.log(find("Find the longest word"));

Related

TypeError: Cannot read properties of undefined (reading 'length'). Codewars task

I write solutions to tasks and got
TypeError: Cannot read properties of undefined (reading 'length').
This is my solution
function sumArray(array) {
if (array === null || array.length < 2) {
return 0;
}
let sum = 0;
for (let i = 0; i < array.length; i++) {
sum += array[i];
}
return sum - Math.max(...array) - Math.min(...array)
}
Could you help me find an error in my code?
undefined is not === with null. You need to test for both before calling length on your argument, or don't call this method with an undefined argument.
You need to check is array even defined and that it is type array.
And I think you need to return 0 in all variant where argument array is not defined or null
if (!array || (Array.isArray(array) && array.length < 2)) {
return 0;
}
Based on the code you provided, it's possible that the error is being caused by calling the sumArray function with an undefined or null value as its argument. The code below is fixed.
function sumArray(array) {
if (!Array.isArray(array) || array.length < 2) {
return 0;
}
let sum = 0;
for (let i = 0; i < array.length; i++) {
sum += array[i];
}
return sum - Math.max(...array) - Math.min(...array);
}

Sum of Digits works in console but not when returned

So I'm doing a codewars challenge and I have no clue why my code isn't working. I'm a beginner so please don't hate on me.
This is my code:
function digital_root(n) {
let str = n.toString()
let arr = []
let sum = 0
for (let i = 0; i < str.length; i++) {
arr.push(str.charAt(i))
}
for (let i = 0; i < str.length; i++) {
sum += Number(arr[i])
}
let sumStr = sum.toString()
if (sumStr.length > 1) {
digital_root(sum)
} else if (sumStr.length == 1) {
return sum
}
}
It works when I console.log it but not when I return the value. I'm trying to learn recursion. Thanks for the help!
You need to return digital_root(sum) too, if sumStr.length > 1 in order to access recursive returned value.
you have to write return digital_root(sum) instead of just digital_root(sum).
check below:
function digital_root(n) {
let str = n.toString()
let arr = []
let sum = 0
for (let i = 0; i < str.length; i++) {
arr.push(str.charAt(i))
}
for (let i = 0; i < str.length; i++) {
sum += Number(arr[i])
}
let sumStr = sum.toString()
if (sumStr.length > 1) {
return digital_root(sum)
} else if (sumStr.length == 1) {
return sum
}
}
console.log("Digital Root :", digital_root('123456789'));
Ok, it seems you are missing dealing with the return value of digital_root when you call it recursively. See added "return" statement below.
function digital_root(n) {
let str = n.toString()
let arr = []
let sum = 0
for (let i = 0; i < str.length; i++) {
arr.push(str.charAt(i))
}
for (let i = 0; i < str.length; i++) {
sum += Number(arr[i])
}
let sumStr = sum.toString()
if (sumStr.length > 1) {
// ***** You need to deal with the return value of digital_root when you call it.
return digital_root(sum)
} else if (sumStr.length == 1) {
return sum
}
}
However, while JavaScript's functional coding style does support recursive functions, we need to be aware that most JavaScript compilers are not currently optimized to support them safely. Recursion is best applied when you need to call the same function repeatedly with different parameters from within a loop.
Please read this,
https://www.sitepoint.com/recursion-functional-javascript/#:~:text=However%2C%20while%20JavaScript's%20functional%20coding,parameters%20from%20within%20a%20loop.

JavaScript TypeError: cannot read property 'split' of undefined

I am getting this typeError with split when I try to run this js. I am unsure of how to fix it, I defined it properly as shown in my textbook.
var current;
var string;
console.log("Enter words separated by spaces.");
prompt(string);
var array = [];
array = string.split(" ");
for(i = 0; i < array.length; i++)
{
var frequency = 0;
current = array[i];
for(i = 0; i < array.length; i++)
{
if(current === array[i])
frequency++;
}
console.log(current + " - " + frequency);
}
}
When running properly the function should produce an output like so: hey - 1.
It counts the frequency of each unique word and displays next to the word the amount of times it appears in the string. Any help would be greatly appreciated thank you.
the main problem is that you were not reading string in from your prompt. I have stored the result as s in my example below.
Also you were using i again in your second for loop. Use another letter for this (the convention is j):
var current;
var string;
var s;
console.log("Enter words separated by spaces.");
s = prompt(string);
var array = [];
array = s.split(" ");
console.log(array);
for(i = 0; i < array.length; i++){
var frequency = 0;
current = array[i];
for(j = 0; j < array.length; j++){
if(current === array[j]) frequency++;
}
console.log(current + " - " + frequency);
}
I hope this helps.
Just little mistakes:
store the prompt in string: string = prompt(string);
give second for loop another variable j, so i won't overwritten.
var current;
var string;
console.log("Enter words separated by spaces.");
string = prompt(string);
var array = [];
array = string.split(" ");
for (i = 0; i < array.length; i++) {
var frequency = 0;
current = array[i];
for (j = 0; j < array.length; j++) {
if (current === array[j])
frequency++;
}
console.log(current + " - " + frequency);
}
Instead of doing split, you can do .splice.
I believe this link is helpful.
However, first, you would have to search through the array for " ".
You can implement this through string.search(" "), which returns where the " " is found.
Furthermore, your syntax for prompt is wrong, it should be:
var something = prompt("Enter words separated by spaces.");

Can anyone explain why I am getting this error in Javascript? [Cannot read property 'length' of undefined]

Here is my code:
function isEven(num) {;
if (num % 2 === 0) {
return true;}
else {
return false;}
}
function convertToIntegers(lst) {
lst.split(' ');
var len = lst.length;
var count = 0;
while (count < len) {
lst[count] = parseInt(lst[count]);
count++}
}
function iqTest(numbers){
var int_list = convertToIntegers(numbers);
var e_list = [];
var o_list = [];
var count = 0;
var len_int = int_list.length;
while (count < len_int) {
if (isEven(int_list[count]) === true) {
e_list.push(count);}
else if (isEven(count) === false) {
o_list.push(count);}
count++}
if (e_list.length < 2 && e_list.length > 0 && o_list.length > 2) {
return e_list[0];}
else if (o_list.length < 2 && o_list.length > 0 && e_list.length > 2) {
return o_list[0];}
}
Everytime I run it I get this error that says "TypeError: Cannot read property 'length' of undefined at iqTest". Can anyone explain to me how I can fix this error. I don't understand why any object would be undefined in my code. Every var declaration I make is complete. I thought undefined only came up if I wrote something like 'var a' without defining it.
Tomer W and Patrick Evans are right. change your helper function
function convertToIntegers(lst) {
lst = lst.split(' ');
var len = lst.length;
var count = 0;
while (count < len) {
lst[count] = parseInt(lst[count]);
count++;
}
return lst;
}
this way you are storing th result of the split and then returning the array when done.
that being said this function isn't needed. Check out the built in array function map
this one is very easy!
in these situations you want to trace the value back.
you use .length in iqTest() in the line var len_int = int_list.length;
the last assignment to int_list is at line var int_list = convertToIntegers(numbers);
glimps at convertToIntegers(numbers) shows no return statement.
therefore conclusion:
convert2Integers() returns nothing into int_list
then you use int_list.length; of undefined
it seems you wish to return lst from convert2Integers()
function convertToIntegers(lst) {
lst = lst.split(' '); // NOTICE CHANGE, + create a different list!
var len = lst.length;
var count = 0;
while (count < len) {
lst[count] = parseInt(lst[count]);
count++
}
return lst; //THIS LINE was Missing!
}
To expand on #Patrick Evans comment you need to save the result of the split then use that for your while loop. Just as a side note you know the number of iterations of the loop so you can use a for loop.
function convertToIntegers(lst) {
//lst.split(' ');
var lst_array = lst.split(' ');
var len = lst_array .length;
var count = 0;
while (count < len) {
lst_array[count] = parseInt(lst_array[count]);
count++}
}
//
//for loop code
//
//for(i=0;i<lst_array.length;i++){
// lst_arry[i] = parseInt(lst_array[i]);
//}

Error while executing mapreduce in mongo-shell

The following error occours
Thu May 23 07:14:53.437 JavaScript execution failed: map reduce failed:{
"errmsg" : "exception: JavaScript execution failed: TypeError: Cannot read property 'product_category' of undefined near '(values[i].product_category)' (line 21)",
"code" : 16722,
"ok" : 0
at src/mongo/shell/collection.js:L970
My map and reduce function are:
map1 = function()
{
emit({Product_id:this.Product_id
},
{
product_category:this.product_category
});
}
reduce1 = function(key, values)
{
var ref = new Array();
var count = 0;
var tmp="";
var pdt_array = new Array();
for (var i = 1; i <= values.length; i++) {
if( i == 1 )
{
pdt_array_array[i] = values[i];
}
else
{
tmp = values[i];
while(i > 1)
{
if(tmp == pdt_array[i])
{
ref.push(values[i].product_category);
count++;
}
i--;
}
pdt_array[i] = tmp;
tmp = "";
}
}
return {product_category:ref, Count:count}
}
db.DummyReverse.mapReduce(map1, reduce1, {out:{reduce:"product_count_while"}})
The issue is that you are not returning the same format from reduce function as you are emitting as value. Since reduce function can be called 0, once or multiple times for each key you must use the exact same format in all of those cases and you cannot assume that your reduce function will be called only once.
Javascript arrays are 0-indexed. So your last for-run want to access a array index, which doesn't exist. I hope I interpret your code right.
[...]
for (var i = 0; i < values.length; i++) {
if ( i == 0) {
pdt_array_array[i] = values[i];
} else {
tmp = values[i];
while(i > 0) {
if(tmp == pdt_array[i]) {
ref.push(values[i].product_category);
count++;
}
i--;
}
pdt_array[i] = tmp;
tmp = "";
}
}
[...]
Take notice at for (var i = 0; i < values.length; i++). So the n-th element has the index n-1. The last element length-1.
Remarks: Are you sure you get no infinite loop with the for-loop increasing i and in the while decreasing it?

Categories