In the example above I get an exception since the values which are stored in the array are just plain HTML code.
No, they're jQuery instances. Calling Number.parseFloat
on a jQuery instance is going to return NaN
*.
You don't need to do anything special if you want to access the text, the entry is a jQuery object, just call .text()
on it directly:
arr[index] = Number.parseFloat(value.text()).toFixed(maxNum);
// ---------------------------------^^^^^^^
* (because parseFloat
will coerce the object to string, getting "[object Object]"
, and "[object Object]"
cannot be parsed to a float)
Having seen the full function, as you said in a comment, you'll want to use .text
on a
as well. Here's that and some other notes:
function removeZeros(arr) {
var map = arr.map(function(a) {
var res, astNumman, m;
// *** Get the text of the entry
a = a.text();
if (a % 1 === 0) { // *** ? `a` is a string. This will coerce it to number and then do % on it.
res = "1";
} else {
lastNumman = a[a.length-1]; // *** Much more efficient than `a.split('').pop();`
if (lastNumman == 0) { // *** Again using a string as a number
m = parseFloat(a);
res = (m + "").split(".")[1].length; // *** The *length* of the fractional portion?
} else {
m = a.split(".")[1].length;
res = m;
}
}
return res;
});
var maxNum = map.reduce(function(a, b) {
return Math.max(a, b);
});
// ***
arr.forEach(function(value, index, arr) {
arr[index] = Number.parseFloat(value.text()).toFixed(maxNum);
});
}
Running Example:
var array=
[
$('*[id$=id1]'),
$('*[id$=id2]'),
$('*[id$=id3]'),
$('*[id$=id4]'),
$('*[id$=id5]')
];
function removeZeros(arr) {
var map = arr.map(function(a) {
var res, astNumman, m;
// *** Get the text of the entry
a = a.text();
if (a % 1 === 0) { // *** ? `a` is a string. This will coerce it to number and then do % on it.
res = "1";
} else {
lastNumman = a[a.length-1]; // *** Much more efficient than `a.split('').pop();`
if (lastNumman == 0) { // *** Again using a string as a number
m = parseFloat(a);
res = (m + "").split(".")[1].length; // *** The *length* of the fractional portion?
} else {
m = a.split(".")[1].length;
res = m;
}
}
return res;
});
var maxNum = map.reduce(function(a, b) {
return Math.max(a, b);
});
// ***
arr.forEach(function(value, index, arr) {
arr[index] = Number.parseFloat(value.text()).toFixed(maxNum);
});
}
removeZeros(array);
console.log(array);
<div id="id1">7</div>
<div id="id2">6.4324</div>
<div id="id3">8.24</div>
<div id="id4">8998.3</div>
<div id="id5">0</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
It seems like the goal of removeZeroes
is to convert the array of jQuery objects into an array of strings with the text of the object converted to number and then to string where they all have the same number of digits after the decimal (the longest one). If so, we can be a bit more efficient about it:
function removeZeros(arr) {
// Find longest decimal portion, convert jQuery objects to numbers
var longest = -Infinity;
arr.forEach(function(entry, index) {
var num = parseFloat(entry.text());
var str = String(num);
var decimal = str.indexOf(".");
var thisLength;
if (decimal === -1) {
thisLength = 1;
} else {
thisLength = str.length - decimal - 1;
}
if (thisLength > longest) {
longest = thisLength;
}
arr[index] = num;
});
// Format numbers as strings
arr.forEach(function(num, index) {
arr[index] = num.toFixed(longest);
});
}
Running Example:
var array=
[
$('*[id$=id1]'),
$('*[id$=id2]'),
$('*[id$=id3]'),
$('*[id$=id4]'),
$('*[id$=id5]')
];
function removeZeros(arr) {
// Find longest decimal portion, convert jQuery objects to numbers
var longest = -Infinity;
arr.forEach(function(entry, index) {
var num = parseFloat(entry.text());
var str = String(num);
var decimal = str.indexOf(".");
var thisLength;
if (decimal === -1) {
thisLength = 1;
} else {
thisLength = str.length - decimal - 1;
}
if (thisLength > longest) {
longest = thisLength;
}
arr[index] = num;
});
// Format numbers as strings
arr.forEach(function(num, index) {
arr[index] = num.toFixed(longest);
});
}
removeZeros(array);
console.log(array);
<div id="id1">7</div>
<div id="id2">6.4324</div>
<div id="id3">8.24</div>
<div id="id4">8998.3</div>
<div id="id5">0</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
There I've used your arr.forEach
-assign-to-arr[index]
pattern rather than map
as you seemed to prefer it (and it does avoid creating two unnecessary arrays).