I am getting NaN and Infinity in getting the max value of my JSON Array object.
I am trying to append the properties of a GeoJSOn data from other JSON.
Here's the JSFiddle for reference.
The snippet:
$.map(data, function (e) {
var dev_id = e.dev_id;
var data = e.data;
for (var j = 0; j < data.length; j++) {
var rainVal = parseFloat(data[j].rain_value);
arr[j] = parseFloat(rainVal);
}
var max = Math.max.apply(Math, arr) * 4;
console.log(dev_id + " " + max)
for (var k = 0; k < len; k++) {
jsonObj_device_id = jsonObj.features[k].properties["device_id"];
if (jsonObj_device_id === dev_id) {
var nameR = "rain_intensity";
var rainValue = max;
jsonObj.features[k].properties[nameR] = rainValue;
}
}
});
There are cases in your code, where in the AJAX response, you are either not getting the Data i.e. e.data or if you get the data you are not getting rain_value. If you do not get e.data first time, you will get Infinity logged on your console because var max = Math.max.apply(Math, []) results in -Infinity. If you do not get rain_value then parseFloat would give you NaN.
Validate the API response before such operations. Something like this.
var dev_id = e.dev_id;
var data = e.data;
var max = 0, r;
var arr = [];
if(data) {
for (var j = 0; j < data.length; j++) {
r = data[j].rain_value || 0;
arr[j] = parseFloat(r);
}
}
if(arr.length) {
max = Math.max.apply(Math, arr) * 4;
}
console.log(dev_id + " " + max);
Here is a working demo
var rainVal = parseFloat(data[j].rain_value);
if (!rainVal) // check 1
rainVal = 0;
arr[j] = parseFloat(rainVal);
}
var max = 0;
if (arr) // check 2
{
maxBeforeTested = Math.max.apply(Math, arr) * 4;
if (isFinite(maxBeforeTested)) //check 3
max = maxBeforeTested;
else
console.log("Had an infinite value here.");
}
console.log("Cleaned output: " + dev_id + " " + max)
Basically, you needed some checks, I have added comments as "Check".
Any number greater than 1.797693134862315E+308 is infinity. Use isFinite() to check.
NaN means not a number value, you can check that using isNaN() or simply if()
Related
I was trying to return the maximum repeated word. However for some reason it doesn't return the max. Here's the code responsible for that:
var max = -Infinity;
for(var prop in myObj){
if(myObj[prop] > max){
max = prop;
}
}
return max;
This one returns "h" w/c is the first element in the word 'helllo'...it supposed to be 'l'...
Right now here's my whole codes:
function findMaxRepeatCountInWord(word) {
var splitWord = word.split('');
var myObj = {};
for(var i = 0; i < splitWord.length; i++){
if(myObj.hasOwnProperty(splitWord[i])){
myObj[splitWord[i]]++;
}else{
myObj[splitWord[i]] = 1;
}
}
var max = -Infinity;
for(var prop in myObj){
if(myObj[prop] > max){
max = prop;
}
}
return max;
}
console.log(findMaxRepeatCountInWord('helllo'));
Any idea what am I missing out?
You are comparing a value at first and then you change max to a key.
I suggest to use max only for the key, with a initializing with the first element of the keys. Then iterate from the second key and check if the value is gereater then the actual max value.
function findMaxRepeatCountInWord(word) {
var splitWord = word.split('');
var myObj = {};
for (var i = 0; i < splitWord.length; i++) {
if (myObj.hasOwnProperty(splitWord[i])) {
myObj[splitWord[i]]++;
} else {
myObj[splitWord[i]] = 1;
}
}
var keys = Object.keys(myObj), // take the keys in an array
max = keys[0]; // initialize with the first key
for (i = 1; i < keys.length; i++) { // iterate from the second key
if (myObj[keys[i]] > myObj[max]) { // check and
max = keys[i]; // update
}
}
return max;
}
console.log(findMaxRepeatCountInWord('helllo'));
max is one of the keys. You should compare the value of that key with the current key prop:
if(myObj[prop] > myObj[max])
// ^^^^^^ ^
Simply loop through each character of the text, then store the occurrence in an object
var getMaxOccurence = function (text)
{
var maxObj = {};
// loop through each character
for (var i = 0; i < text.length; i++)
{
var char = text.charAt(i);
// check if char is in obj
if (!(char in maxObj))
{
// add occurrence
maxObj[char] = 1;
}
else
{
// add occurrence
maxObj[char]++;
}
}
var max = {
value: 0,
key: 0
};
var keys = Object.keys(maxObj);
// here get which character contains the highest value.
for (var i = 0; i < keys.length; i++)
{
if (maxObj[keys[i]] > max.value)
{
max.value = maxObj[keys[i]];
max.key = keys[i];
}
}
// return it
return max;
};
document.getElementById("subject").innerHTML = "helllo";
var result = getMaxOccurence("helllo");
document.getElementById("result").innerHTML = result.key + " ( " + result.value + " ) ";
Subject: <span id="subject"></span>
<br/>
Max occurence: <span id="result"></span>
hope that helps
I am writing a function called "computeAverageOfNumbers".
Given an array of numbers, "computeAverageOfNumbers" returns their average.
Notes:
If given an empty array, it should return 0.
Here's my code:
function computeAverageOfNumbers(nums) {
var total = 0;
for (var i = 0; i < nums.length; i++) {
total += nums[i];
}
var avg = total / nums.length;
return avg;
}
var input = [];
var output = computeAverageOfNumbers(input);
console.log(output); // --> returns NaN instead of 0
As you can see my code returns NaN when you submit an empty array but works if you put regular array items like var input = [1,2,3,4,5];
If given an empty array, it should return 0.
Am I missing something?
Just do below
if( nums.length == 0 ) return 0;
in code
function computeAverageOfNumbers(nums) {
if (nums.length == 0) return 0;
var total = 0;
for (var i = 0; i < nums.length; i++){
total += nums[i];
}
var avg = total / nums.length;
return avg;
}
Just check if nums.length
function computeAverageOfNumbers(nums) {
if (nums.length === 0) {
return 0
} else {
var total = 0;
for (var i = 0; i < nums.length; i++) {
total += nums[i];
}
var avg = total / nums.length;
return avg;
}
}
var input = [];
var output = computeAverageOfNumbers(input);
console.log(output);
input = [2,5,9,13];
output = computeAverageOfNumbers(input);
console.log(output);
When your array is empty, nums.length = 0 and a if you divide a number by 0, it gives you NaN.
Just change
var avg = total / nums.length;
to
var avg = (nums.length)?total/nums.length:0
to solve your trouble
When you pass an empty array then this line:
var avg = total / nums.length;
Is a division by zero, so avg will be NaN. I would short circuit the function at the start with:
if (nums.length === 0)
return 0;
Bear in mind ideally you also want to do some type checking to confirm you've got an array, etc. but the above should give you the basics.
I wanted to:
Return -1 if data(array) is null or empty
If data is not null and if the array has rain_value property I wanted to get the 2nd index value of that array based on its length
Below is the snippet of my code:
success: function (data) {
//console.log(data);
$.map(data, function (e) {
var max = -1;
var dev_id = e.dev_id;
var data = e.data;
var r;
if (data) {
for (var j = 0; j < data.length; j++) {
r = parseFloat(data[j].rain_value) || 0;
arr[j] = parseFloat(r);
}
}
if (arr.length) {
max = arr[1] * 4;
//max = Math.max.apply(Math, arr) * 4;
}
for (var k = 0; k < len; k++) {
var jsonObj_device_id = jsonObj.features[k].properties.device_id;
if (jsonObj_device_id == dev_id) {
var nameR = "rain_intensity";
var rainValue = max;
jsonObj.features[k].properties[nameR] = rainValue;
}
}
console.log(dev_id + " " + max)
});
}
I can't seem to figure out why it works only in some data.
Here's the Fiddle. Thanks!
You are assigning an empty array value to the variable arr outside your loop, but not within the loop. This means that as soon as you have data and that array is populated every following iteration will have array values. You need to clear it every time, or only declare it in the loop...
success: function (data) {
//console.log(data);
$.map(data, function (e) {
var max = -1;
var dev_id = e.dev_id;
var data = e.data;
var r;
arr = []; // <---- clear the array here
if (data) {
for (var j = 0; j < data.length; j++) {
r = parseFloat(data[j].rain_value) || 0;
arr[j] = parseFloat(r);
}
}
if (arr.length) {
max = arr[1] * 4;
//max = Math.max.apply(Math, arr) * 4;
}
for (var k = 0; k < len; k++) {
var jsonObj_device_id = jsonObj.features[k].properties.device_id;
if (jsonObj_device_id == dev_id) {
var nameR = "rain_intensity";
var rainValue = max;
jsonObj.features[k].properties[nameR] = rainValue;
}
}
console.log(dev_id + " " + max)
});
}
Working jsfiddle link
I've got an array that is constantly updating with analogue readings from an Arduino pin.
I'd like to create a function that takes the latest 100 values in the array, and returns an average of them (the array has a max length of 100,000 at which it starts 'shifting' and 'pushing' to make space for new values).
I created this function, but it returns 'NaN' every time:
function returnAverage(){
var averageArray = [];
var sum = 0;
var sampleEnd = values.length
for (var x = sampleEnd - 100; x < sampleEnd; x++) {
averageArray[x] = values[x]
}
for(var i = 0; i < averageArray.length; i++){
sum += parseInt(averageArray[i]);
}
var avg = sum/averageArray.length;
console.log(avg)
}
Any ideas?
If values is a array of numbers, last maximum 100 items average:
function returnAverage(values) {
var arr = values.slice(-100);
return arr.reduce(function(a, b){ return a + b; }, 0) / (arr.length || 1);
}
Issue number one is that the final value of sum and averageArray.lnegth is 0.
It seems this would happen because the "value" array is empty.
See example below:
var values = [0,1,2,3,4,5,6];
var averageArray = [];
var sum = 0;
var sampleEnd = values.length
for (var x = sampleEnd - 7; x < sampleEnd; x++) {
averageArray[x] = values[x]
}
for(var i = 0; i < averageArray.length; i++){
sum += parseInt(averageArray[i]);
}
var avg = sum/averageArray.length;
console.log(avg)
Edit: NaN is a result of division by zero. So you might want to check for that before calculating:
if(sum == 0 || averageArray.length == 0)
{
return 0;
}
As an exercise, I'm trying to create a function that returns the palindromic numbers resulting from multiplying three-digit numbers. As far as I can tell, the function is running through numbers correctly, however, the resulting array is incorrect. I don't need the solution to the palindrome problem...just an idea of what I might be missing. Have I run into some limitation?
var palindromic = function() {
var a = [];
var res = [];
for (var i = 100; i < 1000; i++) {
a.push(i);
}
var ar = a.slice(0);
a.map(function(x) {
for (var j = 0; j < ar.length; j++) {
var result = x * ar[j];
if (result.toString() === result.toString().split("").reverse().join("")) {
res.push(result);
}
}
})
return res;
};
Pretty sure it's just trying to call console.log() 810,000 times. If you comment the console.log line, it works just fine.
var palindromic = function() {
var a = [];
var res = [];
for (var i = 100; i < 1000; i++) {
a.push(i);
}
var ar = a.slice(0);
a.map(function(x) {
for (var j = 0; j < ar.length; j++) {
var result = x * ar[j];
//console.log(x + " : " + ar[j] + ' = ' + result);
if (result.toString() === result.toString().split("").reverse().join("")) {
res.push(result);
}
}
});
return res;
};
console.log(palindromic());