JavaScript sort array by key? - javascript

I have an array with keys like this:
0kefsdfsdf
1101fsdf
55fdsfds
Now I want to sort that array so that the keys start with the smallest number. Afterwards the keys should look like that:
0kefsdfsdf
55fdsf
1101fsdfds
I tried this code, but its not sorting the keys:
myArray.sort(function(a, b) {
return a < b;
});
How can I sort the array according to the keys so that when I iterate the array afterwards, it starts with the key with the lowest number?

You can use
var sorted = myArray.sort(function(a,b){ return parseInt(a,10)-parseInt(b,10) });
This relies on the curious behavior of parseInt which isn't worried when asked to parse "55fdsfds" :
If parseInt encounters a character that is not a numeral in the
specified radix, it ignores it and all succeeding characters and
returns the integer value parsed up to that point. parseInt truncates
numbers to integer values. Leading and trailing spaces are allowed.

Related

String To Number Confusion

Why does parseInt("-1000-500-75-33") return -1000?
Shouldn't it return the sum of those numbers: -1608
How can I get the string "-1000-500-75-33" to return as the sum of those numbers?
parseInt will try to get a number starting from the beginning of the string.
Since - is a valid character to begin a number with, it parses the string until it finds something invalid. The second - is invalid because no integer can contain an - inside it, only digits. So it stops there and considers the number to be "finished".
Now, if you want to process the expression, you can use eval like so:
eval("-1000-500-75-33")
This will return -1608 as expected.
parseInt will not perform any computations, rather it will try to convert a string into an integer. It returns -1000 because the dash afterwards would not be considered a valid number. If you want to sum all these numbers you could split on the dash, map to Number, then reduce:
var numString = "-1000-500-75-33";
numString.split('-').map(e => Number(e)).reduce((a, b) => a - b);
Try to eval! it's safe here
eval("-1000-500-75-33").toString()
console.log(eval("-1000-500-75-33").toString());
And about type casting: After parsing -1000, which is obviously "negative 1000", It will escape casting as soon as it detect a symbol common between numbers & strings. So parseInt is seeing "-1000-500-75-33" as "-1000NotConvertableString", So left the remaining away, returning -1000 as the result of type-casting.
Since they are in a string, ParseInt does not parse the whole string, just finds the first applicable number from the start & returns it. If the start of the string cannot be parsed, it returns NaN
parseInt("-1000NOT_NUMBER") = -1000
parseInt("test-1000`) = NaN
You have to use eval function to do what you want, that evaluates given string as if it were a command entered into the console;
eval("-1000-500-75-33") = -1608

Is it safe to use JavaScript's Math.max on an array of strings?

This seems to work, on an array of strings that look like numbers (they're numbers from a CSV file read in with csv-parse, which seems to convert everything into strings):
var a = ['123.1', '1234.0', '97.43', '5678'];
Math.max.apply(Math, a);
Returns 5678.
Does Math.max convert strings to numbers automatically?
Or should I do a + conversion myself first to be extra safe?
Does Math.max convert strings to numbers automatically?
Quoting the ECMA Script 5.1 Specification for Math.max,
Given zero or more arguments, calls ToNumber on each of the arguments and returns the largest of the resulting values.
So, internally all the values are tried to convert to a number before finding the max value and you don't have to explicitly convert the strings to numbers.
But watch out for the NaN results if the string is not a valid number. For example, if the array had one invalid string like this
var a = ['123.1', '1234.0', '97.43', '5678', 'thefourtheye'];
console.log(Math.max.apply(Math, a));
// NaN
You'll get a NaN if any of the strings aren't numbers, but otherwise it should work fine. I'd add the + just to be safe.
Consider this situation:
<script>
var a=['123.1', '1234.0', '97.43', '5678','0 11111111'];
console.log(Math.max.apply(Math, a));
</script>
You need to cast elements from array to be extra safe..
if you intend to check for the max element in an array of strings using Math.max() method. you can compare the length of reach element
question: var a = ['123.1', '1234.0', '97.43', '5678'];
const checkLength = Math.max.apply(null, a.map(element => element.length));
or using spread operator for shorter form
const checkLength = Math.max(...a.map(element => element.length));
then filter to get all the elements
a.filter(elem => elem.length === checkLength)

Sorting an array of decimal & whole numbers [duplicate]

This question already has answers here:
How to sort an array of integers correctly
(32 answers)
Closed 8 years ago.
I can't seem to figure this one out.
var arr = [2.62, 111.05, 1.05]
arr.sort();
This returns [1.05, 111.05, 2.62], but I'm expecting [1.05, 2.62, 111.05].
How can this be achieved? I've read a bit about writing a custom sort to split the "decimal" but haven't managed to have any success.
By default sorting is alphabetically. You need to pass a function to the sort method
arr.sort(function(a, b){return a-b;});
The sort method compares the items as strings by default. You can specify a comparer function to make the comparison any way you like. This will compare the items as numbers:
arr.sort(function(a, b){ return a - b; });
Note: All numbers in Javascript a double precision floating point numbers, even if they happen to contain an integer value, so integer values and decimal values are not treated differently.
This is the normal behavior for Array.sort() when it isn't given a comparator function. Try this:
var arr = [2.62, 111.05, 1.05];
arr.sort(function(a,b) { return a-b; });
From MDN:
If compareFunction is not supplied, elements are sorted by converting them to strings and comparing strings in Unicode code point order. For example, "Cherry" comes before "banana". In a numeric sort, 9 comes before 80, but because numbers are converted to strings, "80" comes before "9" in Unicode order.

Bug in use of slice() has no effect?

I noticed that the correct
return str.slice(0, res);
returns the same value as the incorrect
var str = "some_string";
return str.slice(str, res);
In this case str is a string and res is a numeric quantity.
My guess is that some how because slice expects a numeric quantity and does not get one ( for the first parameter ), it converts what it finds to a 0.
Is this expected behavior?
JavaScript provides implicit type coercion. That means if an integer is expected (as is the case here), it will convert the value provided to an integer. If no sensible value can be divined, zero is used.
If an integer is provided, great!
If a string is provided and it looks like a integer (e.g. str.slice("5", res)) it will be converted into the expected integer.
If a string is provided and it doesn't look like a number (e.g. str.slice("abc", res)), 0 is used.
My guess is that some how because slice expects a numeric quantity and does not get one ( for the first parameter ), it converts what it finds to a 0.
That's basically what happens. .slice calls ToInteger on the first argument, which in turn calls ToNumber. But if the value cannot be converted to a number (if the result is NaN), it returns 0.
So, if you pass a numeric string as start, .slice would start at the mathematical value of that string. Any other string converts to 0.

Google Spreadsheet Script getValues - Force int instead of string

Is there a way to force .getRange().getValues() to return an int? Although only numbers exist in my range, it is returning them as strings. I would like to avoid using parseInt in every one of my statements or creating a separate array with converted values.
Or is that the only solution, to get the array and then parseInt the entire array in a loop?
you can do this easily using the unary '+' operator as follows:
First get your values from your spreadsheet using getValue() or getValues(). Suppose you get two such values, and store them in A = 1 and B = 2. You can force them to be recognized as numbers by using any math binary operator except for +, which concatenates strings, so A - B = -1, while A + B will return '12'.
You can force the variables to be numbers simply by using the + unary operator with any variable that might be interpreted as a string. For example, +A + +B will return the correct value of 3.
You can use parseInt() or Number()
example
var A='12';var B=5
A+B = 125
parseInt(A)+B = 17
Number(A)+B = 17
That said, getValues() is not supposed to return strings unless values have some space or other non-numeric characters in it... are these values entered manually or come as a result of some function ?
getValues() returns a 2D array of Objects - so these are Strings, Integers or Date objects depending on what these are formatted as in your spreadsheet.
Go back to your spreadsheet and see what the cells that have integer values are formatted as. Format them as integers and you should get back integers.

Categories

Resources