How to convert a string of numbers to an array of numbers? - javascript

I have below string -
var a = "1,2,3,4";
when I do -
var b = a.split(',');
I get b as ["1", "2", "3", "4"]
can I do something to get b as [1, 2, 3, 4] ?

You can use Array.map to convert each element into a number.
var a = "1,2,3,4";
var b = a.split(',').map(function(item) {
return parseInt(item, 10);
});
Check the Docs
Or more elegantly as pointed out by User: thg435
var b = a.split(',').map(Number);
Where Number() would do the rest:check here
Note: For older browsers that don't support map, you can add an implementation yourself like:
Array.prototype.map = Array.prototype.map || function(_x) {
for(var o=[], i=0; i<this.length; i++) {
o[i] = _x(this[i]);
}
return o;
};

My 2 cents for golfers:
b="1,2,3,4".split`,`.map(x=>+x)
backquote is string litteral so we can omit the parenthesis (because of the nature of split function) but it is equivalent to split(','). The string is now an array, we just have to map each value with a function returning the integer of the string so x=>+x (which is even shorter than the Number function (5 chars instead of 6)) is equivalent to :
function(x){return parseInt(x,10)}// version from techfoobar
(x)=>{return parseInt(x)} // lambda are shorter and parseInt default is 10
(x)=>{return +x} // diff. with parseInt in SO but + is better in this case
x=>+x // no multiple args, just 1 function call
I hope it is a bit more clear.

This is very simple.Such as:
["1", "2", "3", "4"].map(i=>Number(i))
you can run the demo.
let result = ["1", "2", "3", "4"].map(i=>Number(i));
console.log(result);

Array.from() for details go to MDN
let a = "1,2,3,4";
let b = Array.from(a.split(','),Number);
or
let c = ["1", "2", "3", "4"].map(Number);
b and c is an array of numbers.
demonstration:
let a = "1,2,3,4";
let b = Array.from(a.split(','),Number);
let c = ["1", "2", "3", "4"].map(Number);
console.log(`b: ${b}, c: ${c}`);

Map it to integers:
a.split(',').map(function(i){
return parseInt(i, 10);
})
map looks at every array item, passes it to the function provided and returns an array with the return values of that function. map isn't available in old browsers, but most libraries like jQuery or underscore include a cross-browser version.
Or, if you prefer loops:
var res = a.split(",");
for (var i=0; i<res.length; i++)
{
res[i] = parseInt(res[i], 10);
}

+string will try to change the string to a number. Then use Array.map function to change every element.
"1,2,3,4".split(',').map(function(el){ return +el;});

A more shorter solution: map and pass the arguments to Number:
var a = "1,2,3,4";
var b = a.split(',');
console.log(b);
var c = b.map(Number);
console.log(c);

One liner
Array.from(a.split(','), Number)

There's no need to use lambdas and/or give radix parameter to parseInt, just use parseFloat or Number instead.
Reasons:
It's working:
var src = "1,2,5,4,3";
var ids = src.split(',').map(parseFloat); // [1, 2, 5, 4, 3]
var obj = {1: ..., 3: ..., 4: ..., 7: ...};
var keys= Object.keys(obj); // ["1", "3", "4", "7"]
var ids = keys.map(parseFloat); // [1, 3, 4, 7]
var arr = ["1", 5, "7", 11];
var ints= arr.map(parseFloat); // [1, 5, 7, 11]
ints[1] === "5" // false
ints[1] === 5 // true
ints[2] === "7" // false
ints[2] === 7 // true
It's shorter.
It's a tiny bit quickier and takes advantage of cache, when parseInt-approach - doesn't:
// execution time measure function
// keep it simple, yeah?
> var f = (function (arr, c, n, m) {
var i,t,m,s=n();
for(i=0;i++<c;)t=arr.map(m);
return n()-s
}).bind(null, "2,4,6,8,0,9,7,5,3,1".split(','), 1000000, Date.now);
> f(Number) // first launch, just warming-up cache
> 3971 // nice =)
> f(Number)
> 3964 // still the same
> f(function(e){return+e})
> 5132 // yup, just little bit slower
> f(function(e){return+e})
> 5112 // second run... and ok.
> f(parseFloat)
> 3727 // little bit quicker than .map(Number)
> f(parseFloat)
> 3737 // all ok
> f(function(e){return parseInt(e,10)})
> 21852 // awww, how adorable...
> f(function(e){return parseInt(e)})
> 22928 // maybe, without '10'?.. nope.
> f(function(e){return parseInt(e)})
> 22769 // second run... and nothing changes.
> f(Number)
> 3873 // and again
> f(parseFloat)
> 3583 // and again
> f(function(e){return+e})
> 4967 // and again
> f(function(e){return parseInt(e,10)})
> 21649 // dammit 'parseInt'! >_<
Notice: In Firefox parseInt works about 4 times faster, but still slower than others. In total: +e < Number < parseFloat < parseInt

As a variant you can use combiantion _.map and _.ary methods from the lodash library. Whole transformation will be a more compact. Here is example from the official documentation:
_.map(['6', '8', '10'], _.ary(parseInt, 1));
// → [6, 8, 10]

Use Array.from for this, Try this:
let b = ["1", "2", "3", "4"];
b = Array.from(b,Number);
console.log(b);

The underscore js way -
var a = "1,2,3,4",
b = a.split(',');
//remove falsy/empty values from array after split
b = _.compact(b);
//then Convert array of string values into Integer
b = _.map(b, Number);
console.log('Log String to Int conversion #b =', b);

Matt Zeunert's version with use arraw function (ES6)
const nums = a.split(',').map(x => parseInt(x, 10));

This works amazing if you need to convert an array of strings to numbers.
const numbers = arr => arr.map(Number);
numbers(['1', '2', '3','4']); // [1, 2, 3, 4]

Since all the answers allow NaN to be included, I thought I'd add that if you want to quickly cast an array of mixed values to numbers you can do.
var a = "1,2,3,4,foo,bar";
var b = a.split(',');
var result = b.map(_=>_|0) // Floors the number (32-bit signed integer) so this wont work if you need all 64 bits.
// or b.map(_=>_||0) if you know your array is just numbers but may include NaN.

You can use JSON.parse, adding brakets to format Array
const a = "1,2,3,4";
const myArray = JSON.parse(`[${a}]`)
console.log(myArray)
console.info('pos 2 = ', myArray[2])

You can transform array of strings to array of numbers in one line:
const arrayOfNumbers = arrayOfStrings.map(e => +e);

let ar = [ '682', '874', '906', '11168', '73714',
'74377', '74034', '138860', '138891', '139161', '139562',
'139733', '139560', '74049', '139759', '139934', '140104',
'141335', '141356', '141334', '141337', '141360', '141358',
'141365', '141419', '143333', '151477', '147342', '141355',
'167847', '192141', '196760', '191687', '197351', '197055',
'198852', '198731', '198816', '199034', '200053', '199226',
'217818', '200055', '222039', '230533', '230530', '231127',
'222042', '231100', '236171', '236913', '236980', '237015',
'237016', '237052', '237551', '237560', '237590', '237637',
'237733', '237731', '237655', '238890', '238910', '238837',
'238926', '238972', '238925', '239755', '239696', '239898',
'240037', '239909', '240036', '240082', '240097', '240526',
'240770', '678151', '678950', '678985'];
let arry=[]
ar.map(arr=>{
arry.push(parseInt(arr))
});
console.log(arry);

Related

How do I separate an integer into separate digits in an array in JavaScript?

This is my code so far:
var n = 123456789;
var d = n.toString().length;
var digits = [];
var squaredDigits = [];
for (i = d; i >= 1; i--) {
var j = k / 10;
var r = (n % k / j) - 0.5;
var k = Math.pow(10, i);
var result = r.toFixed();
digits.push(result);
}
console.log(digits);
But when I run my code I get this: [9, 1, 2, 3, 4, 5, 6, 7, 8]
If anyone can see the problem or find a better solution I would very much appreciate it!
Why not just do this?
var n = 123456789;
var digits = (""+n).split("");
What about:
const n = 123456;
Array.from(n.toString()).map(Number);
// [1, 2, 3, 4, 5, 6]
(123456789).toString(10).split("")
^^ this will return an array of strings
(123456789).toString(10).split("").map(function(t){return parseInt(t)})
^^ this will return an array of ints
I realize this was asked several months ago, but I have an addition to samccone's answer which is more succinct but I don't have the rep to add as a comment!
Instead of:
(123456789).toString(10).split("").map(function(t){return parseInt(t)})
Consider:
(123456789).toString(10).split("").map(Number)
Modified the above answer a little bit. We don't really have to call the 'map' method explicitly, because it is already built-in into the 'Array.from' as a second argument.
As of MDN.
Array.from(arrayLike[, mapFn[, thisArg]])
let num = 1234;
let arr = Array.from(String(num), Number);
console.log(arr); // [1, 2, 3, 4]
const toIntArray = (n) => ([...n + ""].map(v => +v))
It is pretty short using Array destructuring and String templates:
const n = 12345678;
const digits = [...`${n}`];
console.log(digits);
Assuming the value n:
const n = 123456789
A minimal ES6 version if you'd like:
String(n).split("").map(Number)
An even shorter but less readable version:
[...String(n)].map(Number)
Want to go even shorter (but less readable)?
[...`${n}`].map(Number)
Shorter you say (and basically illegible)!?
[...""+n].map(Number)
Now you're a real programmer, congrats!
Side note
These aren't really efficient (as most in this thread) since you're allocating 2 arrays instead of 1. Want to be more efficient? Try this which only allocates one array:
var arr = []
var str = String(n)
for (var i = 0; i < str.length; i++) {
arr.push(Number(str[i]))
}
Oldschool but more efficient, huzzah!
It's very simple, first convert the number to string using the toString() method in JavaScript and then use split() method to convert the string to an array of individual characters.
For example, the number is num, then
const numberDigits = num.toString().split('');
This will work for a number greater than 0. You don't need to convert the number into string:
function convertNumberToDigitArray(number) {
const arr = [];
while (number > 0) {
let lastDigit = number % 10;
arr.push(lastDigit);
number = Math.floor(number / 10);
}
return arr;
}
You can get a list of string from your number, by converting it to a string, and then splitting it with an empty string. The result will be an array of strings, each containing a digit:
const num = 124124124
const strArr = `${num}`.split("")
OR to build on this, map each string digit and convert them to a Number:
const intArr = `${num}`.split("").map(x => Number(x))
Here's an alternative to Nicolás Fantone's answer. You could argue it's maybe a little less readable. The emphasis is that Array.from() can take an optional map function as a parameter. There are some performance gains this way since no intermediate array gets created.
const n = 123456;
Array.from(n.toString(), (val) => Number(val)); // [1, 2, 3, 4, 5, 6]
const number = 1435;
number.toString().split('').map(el=>parseInt(el));
let input = 12345664
const output = []
while (input !== 0) {
const roundedInput = Math.floor(input / 10)
output.push(input - roundedInput * 10)
input = roundedInput
}
console.log(output)
Suppose,
let a = 123456
First we will convert it into string and then apply split to convert it into array of characters and then map over it to convert the array to integer.
let b = a.toString().split('').map(val=>parseInt(val))
console.log(b)
Move:
var k = Math.pow(10, i);
above
var j = k / 10;
var num = 123456789;
num = num.toString(); //'123456789'
var digits = num.split(""); //[ '1', '2', '3', '4', '5', '6', '7', '8', '9' ]
It's been a 5+ years for this question but heay always welcome to the efficient ways of coding/scripting.
var n = 123456789;
var arrayN = (`${n}`).split("").map(e => parseInt(e))
Another method here. Since number in Javascript is not splittable by default, you need to convert the number into a string first.
var n = 123;
n.toString().split('').map(Number);
I ended up solving it as follows:
const n = 123456789;
let toIntArray = (n) => ([...n + ""].map(Number));
console.log(toIntArray(n));
Update with string interpolation in ES2015.
const num = 07734;
let numStringArr = `${num}`.split('').map(el => parseInt(el)); // [0, 7, 7, 3, 4]
var n = 38679;
var digits = n.toString().split("");
console.log(digits);
Now the number n is divided to its digits and they are presented in an array, and each element of that array is in string format. To transform them to number format do this:
var digitsNum = digits.map(Number);
console.log(digitsNum);
Or get an array with all elements in number format from the beginning:
var n = 38679;
var digits = n.toString().split("").map(Number);
console.log(digits);
This is actually the cleanest solution I think.
var n = 123456789;
const digits = (`${n}`).split('')
You put it in a string literal but it is kept as numbers, and then it is split to an array and assigned to digits.
const toIntArray = (n) => ([...n + ""].map(v => +v))

Is there a shortcut to create padded array in JavaScript?

I have this javascript:
function padded_array(k, value){
var a = [];
a[k] = value;
return a;
}
padded_array(3, "hello"); //=> [undefined, undefined, undefined, 'hello']
Is it possible to shorten the code in the function body?
for all the googlers coming here - you're probably looking for this:
var pad_array = function(arr,len,fill) {
return arr.concat(Array(len).fill(fill)).slice(0,len);
}
From 2020 & 2021 : straight forward options
Let assume that is your Array
const yourArray = [1,2]
If you just want to loop 4 times (maybe for react jsx )
Array.from({length:4}) //[undefined,undefined,undefined,undefined]
Array(4).fill()//[undefined,undefined,undefined,undefined]
If you want to loop yourArray 4 times, but to start with values you already have
// unmutation option
Array.from({...yourArray, length:4}) //[1,2,undefined,undefined]
// unmutation option, but need some calcualtion
[...yourArray , ...Array(2) ] //[1,2,undefined,undefined]
[...Array(2), ...yourArray ] //[undefined,undefined,1,2]
// loop on your array several times
Array(3).fill(yourArray).flat() // [1, 2, 1, 2, 1, 2]
// mutation the original array.
yourArray.length = 4;
Array.from(yourArray) //[1,2,undefined,undefined]
If You actually want an Array with full of values. ex. with increment numbers.
Remap it
// unmutation option
Array.from({...yourArray,length:4}, (v,i) => v ?? i+1 )
// [1,'2',3, 4]
// Or, mutation the original array. and fill with "x"
array.yourArray.length = 4;
Array.from(yourArray, (v) => v ?? 'x')
// [1,'2','x','x']
If you want to exclude the 'hello', you can use
new Array(count);
to create padded Arrays.
Edit: Maybe like this ?
new Array(5).concat("hello")
Another solution using spread operator:
padArray = (length, value) => [...Array(length).fill(), value];
And the usage is the same as you mentioned:
padded_array(3, "hello"); //=> [undefined, undefined, undefined, 'hello']
For padding at the start:
function padArrayStart(arr, len, padding){
return Array(len - arr.length).fill(padding).concat(arr);
}
Demo:
function padArrayStart(arr, len, padding){
return Array(len - arr.length).fill(padding).concat(arr);
}
console.log(...padArrayStart([1,2,3], 5, 0));//0 0 1 2 3
console.log(...padArrayStart([4,5,6], 3, 0));//4 5 6
For padding at the end:
function padArrayEnd(arr, len, padding){
return arr.concat(Array(len - arr.length).fill(padding));
}
Demo:
function padArrayEnd(arr, len, padding){
return arr.concat(Array(len - arr.length).fill(padding));
}
console.log(...padArrayEnd(['a','b','c'], 10, 'z'));//a b c z z z z z z z
console.log(...padArrayEnd([0, 'a', 'd'], 6, -1));//0 a d -1 -1 -1
Not in standard ES5 or predecessor. Surely you can do something like $.extend([], {"3": "hello"}) in jQuery; you can even do
Object.create(Array.prototype, {"3": {value: "hello"} });
in bare ES5, but it is hack, I would not consider this a solution (if it is ok with you, you can adopt it).
You can use that if your JS doesn't support Array.prototype.fill() (ex. Google Apps Script) and you can't use the code from the first answer:
function array_pad(array, length, filler)
{
if(array.length < length)// [10.02.20] Fixed error that Dimitry K noticed
while(true)
if(array.push(filler) >= length)
break;
return array;
}
I know this is an old(er) question but wanted to add my 2 cents if someone stumbles here (like i initially did).
Anyway, heres my take with Array.from
const padded_array = (k, value) => Array.from({ length: k }).concat(value)
console.log(padded_array(3, "hello"));
Also you could do it with something like this:
const padded = (arr, pad, val) => {
arr[pad] = val
return arr
}
console.log(padded([],3,'hello'))
// push is faster than concat
// mutate array in place + return array
const pad_right = (a, l, f) =>
!Array.from({length: l - a.length})
.map(_ => a.push(f)) || a;
const a = [1, 2];
pad_right(a, 4, 'x');
// -> [ 1, 2, 'x', 'x' ]
a;
// -> [ 1, 2, 'x', 'x' ]
function leftPad(array, desiredLength, padding) {
array.unshift(...Array(desiredLength - array.length).fill(padding));
}
function rightPad(array, desiredLength, padding) {
array.push(...Array(desiredLength - array.length).fill(padding));
}
const myHello = ['hello'];
leftPad(myHello, 3, undefined);
// [undefined, undefined, 'hello']
const myHello2 = ['hello2'];
rightPad(myHello, 3, 0);
// ['hello2', 0, 0];

JavaScript Number Split into individual digits

I am trying to solve a math problem where I take a number e.g. 45, or 111 and then split the number into separate digits e.g. 4 5 or 1 1 1. I will then save each number to a var to run a method on. Does anyone know how to split a number into individual digitals?
For example I have a loop that runs on an array :
for (var i = 0; i < range.length; i++) {
var n = range[i];
}
For each number, I would like to split its digits and add them together?
var num = 123456;
var digits = num.toString().split('');
var realDigits = digits.map(Number)
console.log(realDigits);
var number = 12354987,
output = [],
sNumber = number.toString();
for (var i = 0, len = sNumber.length; i < len; i += 1) {
output.push(+sNumber.charAt(i));
}
console.log(output);
/* Outputs:
*
* [1, 2, 3, 5, 4, 9, 8, 7]
*/
UPDATE: Calculating a sum
for (var i = 0, sum = 0; i < output.length; sum += output[i++]);
console.log(sum);
/*
* Outputs: 39
*/
You can also do it in the "mathematical" way without treating the number as a string:
var num = 278;
var digits = [];
while (num != 0) {
digits.push(num % 10);
num = Math.trunc(num / 10);
}
digits.reverse();
console.log(digits);
One upside I can see is that you won't have to run parseInt() on every digit, you're dealing with the actual digits as numeric values.
This is the shortest I've found, though it does return the digits as strings:
let num = 12345;
[...num+''] //["1", "2", "3", "4", "5"]
Or use this to get back integers:
[...num+''].map(n=>+n) //[1, 2, 3, 4, 5]
I will provide a variation on an answer already given so you can see a different approach that preserves the numeric type all along:
var number = 12354987,
output = [];
while (number) {
output.push(number % 10);
number = Math.floor(number/10);
}
console.log(output.reverse().join(',')); // 1,2,3,5,4,9,8,7
I've used a technique such as the above to good effect when converting a number to Roman numerals, which is one of my favorite ways to begin to learn a programming language I'm not familiar with. For instance here is how I devised a way to convert numbers to Roman numerals with Tcl slightly after the turn of the century: http://code.activestate.com/recipes/68379-conversion-to-roman-numerals/
The comparable lines in my Tcl script being:
while {$arabic} {
set digit [expr {$arabic%10}]
set arabic [expr {$arabic/10}]
// Split positive integer n < 1e21 into digits:
function digits(n) {
return Array.from(String(n), Number);
}
// Example:
console.log(digits(1234)); // [1, 2, 3, 4]
You can work on strings instead of numbers to achieve this. You can do it like this
(111 + '').split('')
This will return an array of strings ['1','1','1'] on which you can iterate upon and call parseInt method.
parseInt('1') === 1
If you want the sum of individual digits, you can use the reduce function (implemented from Javascript 1.8) like this
(111 + '').split('').reduce(function(previousValue, currentValue){
return parseInt(previousValue,10) + parseInt(currentValue,10);
})
Use String, split and map :
String(number).split("").map(Number);
function splitNum(num) {
return String(num).split("").map(Number);
}
console.log(splitNum(1523)); // [1, 5, 2, 3]
console.log(splitNum(2341)); // [2, 3, 4, 1]
console.log(splitNum(325)); // [3, 2, 5]
Without converting to string:
function toDigits(number) {
var left;
var results = [];
while (true) {
left = number % 10;
results.unshift(left);
number = (number - left) / 10;
if (number === 0) {
break;
}
}
return results;
}
Using String, ... and map
const num = 7890;
const digits = [...String(num)].map(Number);
console.log(digits)
Alternatively, using ... and reduce to get digits and their sum.
const sumOfDigits = num => [...""+num].reduce((acc, dig) => acc + +dig, 0);
console.log('Sum of digits: ', sumOfDigits(7890));
Separate each 2 parametr.
function separator(str,sep) {
var output = '';
for (var i = str.length; i > 0; i-=2) {
var ii = i-1;
if(output) {
output = str.charAt(ii-1)+str.charAt(ii)+sep+output;
} else {
output = str.charAt(ii-1)+str.charAt(ii);
}
}
return output;
}
console.log(separator('123456',':')); //Will return 12:34:56
With ES6, you could use Array.from with a stringed number as iterables and Number as mapping function.
const getDigits = n => Array.from(n.toString(), Number);
console.log(getDigits(12345));
A fun introduction to recursion. This answer takes a Number and returns an array of Number digits. It does not convert the number to a string as an intermediate step.
Given n = 1234,
n % 10 will return first (right-moist) digit, 4
n / 10 will return 123 with some remainder
Using Math.floor we can chop the remainder off
Repeating these steps, we can form the entire result
Now we just have to build the recursion condition,
If the number is already a single digit (n < 10), return an array singleton of the digit
otherwise (inductive) the number is 10 or greater; recur and prepend to the first digit
const digits = (n = 0) =>
n < 10
? [ n ]
: [ ... digits (Math.floor (n / 10)), n % 10 ]
console.log (digits ()) // [ 0 ]
console.log (digits (1)) // [ 1 ]
console.log (digits (12)) // [ 1, 2 ]
console.log (digits (123)) // [ 1, 2, 3 ]
console.log (digits (11234)) // [ 1, 2, 3, 4 ]
console.log (digits (123456789012))
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2 ]
This also works:
var number = 12354987;
console.log(String(number).split('').map(Number));
Shadow Wizard , extended version by Orien
var num:Number = 1523;
var digits:Array = [];
var cnt:int = 0;
while (num > 0) {
var mod:int = num % 10;
digits.push(mod * Math.pow(10, cnt))
num = Math.floor(num / 10);
cnt++;
}
digits.reverse();
trace(digits);
output:1000,500,20,3
A functional approach in order to get digits from a number would be to get a string from your number, split it into an array (of characters) and map each element back into a number.
For example:
var number = 123456;
var array = number.toString()
.split('')
.map(function(item, index) {
return parseInt(item);
});
console.log(array); // returns [1, 2, 3, 4, 5, 6]
If you also need to sum all digits, you can append the reduce() method to the previous code:
var num = 123456;
var array = num.toString()
.split('')
.map(function(item, index) {
return parseInt(item);
})
.reduce(function(previousValue, currentValue, index, array) {
return previousValue + currentValue;
}, 0);
console.log(array); // returns 21
As an alternative, with ECMAScript 2015 (6th Edition), you can use arrow functions:
var number = 123456;
var array = number.toString().split('').map((item, index) => parseInt(item));
console.log(array); // returns [1, 2, 3, 4, 5, 6]
If you need to sum all digits, you can append the reduce() method to the previous code:
var num = 123456;
var result = num.toString()
.split('')
.map((item, index) => parseInt(item))
.reduce((previousValue, currentValue) => previousValue + currentValue, 0);
console.log(result); // returns 21
I used this simple way of doing it.
To split digits
var N = 69;
var arr = N.toString().split('').map(Number)
// outputs [6,9]
console.log( arr );
To add them together
console.log(arr.reduce( (a,b) => a+b )); // 15
And the easiest.... num_string.split('').map(Number)
Try below:
console.log((''+123).split('').map(Number))
To just split an integer into its individual digits in the same order, Regular Expression is what I used and prefer since it prevents the chance of loosing the identity of the numbers even after they have been converted into string.
The following line of code convert the integer into a string, uses regex to match any individual digit inside the string and return an array of those, after which that array is mapped to be converted back to numbers.
const digitize = n => String(n).match(/\d/g).map(Number);
I might be wrong, but a solution picking up bits and pieces. Perhaps, as I still learning, is that the functions does many things in the same one. Do not hesitate to correct me, please.
const totalSum = (num) => [...num + ' '].map(Number).reduce((a, b) => a + b);
So we take the parameter and convert it to and arr, adding empty spaces. We do such operation in every single element and push it into a new array with the map method. Once splited, we use reduce to sum all the elements and get the total.
As I said, don't hesitate to correct me or improve the function if you see something that I don't.
Almost forgot, just in case:
const totalSum = (num) => ( num === 0 || num < 0) ? 'I need a positive number' : [...num + ' '].map(Number).reduce((a, b) => a + b);
If negatives numbers or just plain zero go down as parameters. Happy coding to us all.
I am posting this answer to introduce the use of unshift which is a modern solution. With push, you add to the end of an array while unshift adds to the beginning. This makes the mathematical approach more powerful as you won't need to reverse anymore.
let num = 278;
let digits = [];
while (num > 0) {
digits.unshift(num % 10);
num = parseInt(num / 10);
}
console.log(digits);
var num = 111,
separateDigits = num.toString().split(""), i, l = separateDigits.length;
for( i = 0; i < l; ++i ) {
someObject.someMethod( +separateDigits[i] );
}
You can try this.
var num = 99;
num=num.toString().split("").map(value=>parseInt(value,10)); //output [9,9]
Hope this helped!
function iterateNumber(N, f) {
let n = N;
var length = Math.log(n) * Math.LOG10E + 1 | 0;
for (let i = 0; i < length; i++) {
const pow = Math.pow(10, length - i - 1)
let c = (n - (n % pow)) / pow
f(c, i)
n %= pow
}
}
('' + 123456789).split('').map( x => +x ).reduce( (a,b) => a+b ) === 45
true
or without map
('' + 123456789).split('').reduce( (a,b) => (+a)+(+b) ) === 45
true
You can do it in single line, seperate each digits than add them together :
var may = 12987;
var sep = (""+may).split("").map(n=>+n).reduce((a,b)=>a+b);
This is my short solution.. with sum of number
function sum (num) {
let sNumber = num
.toString()
.split('')
.reduce((el1, el2) => {
return Number(el1) + Number(el2)
}, 0)
return sNumber
}
console.log(sum(123))
console.log(sum(456))
javascript has a function for it and you can use it easily.
console.log(new Intl.NumberFormat().format(number));
for example :
console.log(new Intl.NumberFormat().format(2334325443534));
==> 2,334,325,443,534
Iterate through each number with for...of statement.
By adding a + sign before a String, it will be converted into a number.
const num = 143,
digits = [];
for (const digit of `${num}`) {
digits.push(+digit)
}
console.log(digits);
Inspired by #iampopov You can write it with spread syntax.
const num = 143;
const digits = [...`${num}`].map(Number);
console.log(digits);
And as a one liner.
console.log(Number.MAX_SAFE_INTEGER.toString().split('').reduce((pv, v) => Number(v) + pv, 0));

jQuery inArray - problems

Say I have a variable a with the value:
1
Then I have an array b with the values:
[1, 2]
Why does $.inArray(a, b) give me a -1? I should be getting 0, right?
Exactly what you described gives me 0[fiddle]:
var a = 1, b = [1, 2];
alert($.inArray(a, b)); // alerts "0"
However, I can replicate your results when I do this (as suggested by IAbstractDownvoteFactory):
var a = 1, b = ["1", "2"];
alert($.inArray(a, b)); // alerts "-1"
var a = "1", b = [1, 2];
alert($.inArray(a, b)); // alerts "-1"
.inArray only finds matches that are the same type as what you're searching with (they're compared with ===). If you can't make your input data the right format, you can do it yourself:
To convert a to a number:
a = +a; // or a = Number(a);
To convert all elements of b to numbers:
for (var i = 0; i < b.length; i++) {
b[i] = +b[i];
}
Rather than convert to numbers it may be better to convert to strings, such as in an instance where you are usings ids for say a plot where in some case they will numeric entity id and in others case a string, e.g. country code for United Kingdom is GB.
Ensure all values are set as strings
Arr[] = mixedValue.toString();
And then always ensure your comparison needle is a string
if ($.inArray(needle.toString(), Arr) === -1) {
// nope
} else {
// yep
}

How to count certain elements in array?

I have an array:
[1, 2, 3, 5, 2, 8, 9, 2]
I would like to know how many 2s are in the array.
What is the most elegant way to do it in JavaScript without looping with for loop?
[this answer is a bit dated: read the edits, in the notion of 'equal' in javascript is ambiguous]
Say hello to your friends: map and filter and reduce and forEach and every etc.
(I only occasionally write for-loops in javascript, because of block-level scoping is missing, so you have to use a function as the body of the loop anyway if you need to capture or clone your iteration index or value. For-loops are more efficient generally, but sometimes you need a closure.)
The most readable way:
[....].filter(x => x==2).length
(We could have written .filter(function(x){return x==2}).length instead)
The following is more space-efficient (O(1) rather than O(N)), but I'm not sure how much of a benefit/penalty you might pay in terms of time (not more than a constant factor since you visit each element exactly once):
[....].reduce((total,x) => (x==2 ? total+1 : total), 0)
or as a commenter kindly pointed out:
[....].reduce((total,x) => total+(x==2), 0)
(If you need to optimize this particular piece of code, a for loop might be faster on some browsers... you can test things on jsperf.com.)
You can then be elegant and turn it into a prototype function:
[1, 2, 3, 5, 2, 8, 9, 2].count(2)
Like this:
Object.defineProperties(Array.prototype, {
count: {
value: function(value) {
return this.filter(x => x==value).length;
}
}
});
You can also stick the regular old for-loop technique (see other answers) inside the above property definition (again, that would likely be much faster).
2017 edit:
Whoops, this answer has gotten more popular than the correct answer. Actually, just use the accepted answer. While this answer may be cute, the js compilers probably don't (or can't due to spec) optimize such cases. So you should really write a simple for loop:
Object.defineProperties(Array.prototype, {
count: {
value: function(query) {
/*
Counts number of occurrences of query in array, an integer >= 0
Uses the javascript == notion of equality.
*/
var count = 0;
for(let i=0; i<this.length; i++)
if (this[i]==query)
count++;
return count;
}
}
});
You could define a version .countStrictEq(...) which used the === notion of equality. The notion of equality may be important to what you're doing! (for example [1,10,3,'10'].count(10)==2, because numbers like '4'==4 in javascript... hence calling it .countEq or .countNonstrict stresses it uses the == operator.)
Caveat:
Defining a common name on the prototype should be done with care. It is fine if you control your code, but bad if everyone wants to declare their own [].count function, especially if they behave differently. You may ask yourself "but .count(query) surely sounds quite perfect and canonical"... but consider perhaps you could do something like [].count(x=> someExpr of x). In that case you define functions like countIn(query, container) (under myModuleName.countIn), or something, or [].myModuleName_count().
Also consider using your own multiset data structure (e.g. like python's 'collections.Counter') to avoid having to do the counting in the first place. This works for exact matches of the form [].filter(x=> x==???).length (worst case O(N) down to O(1)), and modified will speed up queries of the form [].filter(filterFunction).length (roughly by a factor of #total/#duplicates).
class Multiset extends Map {
constructor(...args) {
super(...args);
}
add(elem) {
if (!this.has(elem))
this.set(elem, 1);
else
this.set(elem, this.get(elem)+1);
}
remove(elem) {
var count = this.has(elem) ? this.get(elem) : 0;
if (count>1) {
this.set(elem, count-1);
} else if (count==1) {
this.delete(elem);
} else if (count==0)
throw `tried to remove element ${elem} of type ${typeof elem} from Multiset, but does not exist in Multiset (count is 0 and cannot go negative)`;
// alternatively do nothing {}
}
}
Demo:
> counts = new Multiset([['a',1],['b',3]])
Map(2) {"a" => 1, "b" => 3}
> counts.add('c')
> counts
Map(3) {"a" => 1, "b" => 3, "c" => 1}
> counts.remove('a')
> counts
Map(2) {"b" => 3, "c" => 1}
> counts.remove('a')
Uncaught tried to remove element a of type string from Multiset, but does not exist in Multiset (count is 0 and cannot go negative)
sidenote: Though, if you still wanted the functional-programming way (or a throwaway one-liner without overriding Array.prototype), you could write it more tersely nowadays as [...].filter(x => x==2).length. If you care about performance, note that while this is asymptotically the same performance as the for-loop (O(N) time), it may require O(N) extra memory (instead of O(1) memory) because it will almost certainly generate an intermediate array and then count the elements of that intermediate array.
Modern JavaScript:
Note that you should always use triple equals === when doing comparison in JavaScript (JS). The triple equals make sure, that JS comparison behaves like double equals == in other languages (there is one exception, see below). The following solution shows how to solve this the functional way, which will ensure that you will never have out of bounds error:
// Let has local scope
let array = [1, 2, 3, 5, 2, 8, 9, 2]
// Functional filter with an Arrow function
// Filter all elements equal to 2 and return the length (count)
array.filter(x => x === 2).length // -> 3
The following anonymous Arrow function (lambda function) in JavaScript:
(x) => {
const k = 2
return k * x
}
may be simplified to this concise form for a single input:
x => 2 * x
where the return is implied.
Always use triple equals: === for comparison in JS, with the exception of when checking for nullability: if (something == null) {} as it includes a check for undefined, if you only use double equals as in this case.
Very simple:
var count = 0;
for(var i = 0; i < array.length; ++i){
if(array[i] == 2)
count++;
}
2017:
If someone is still interested in the question, my solution is the following:
const arrayToCount = [1, 2, 3, 5, 2, 8, 9, 2];
const result = arrayToCount.filter(i => i === 2).length;
console.log('number of the found elements: ' + result);
Here is an ES2017+ way to get the counts for all array items in O(N):
const arr = [1, 2, 3, 5, 2, 8, 9, 2];
const counts = {};
arr.forEach((el) => {
counts[el] = counts[el] ? (counts[el] + 1) : 1;
});
You can also optionally sort the output:
const countsSorted = Object.entries(counts).sort(([_, a], [__, b]) => a - b);
console.log(countsSorted) for your example array:
[
[ '2', 3 ],
[ '1', 1 ],
[ '3', 1 ],
[ '5', 1 ],
[ '8', 1 ],
[ '9', 1 ]
]
If you are using lodash or underscore the _.countBy method will provide an object of aggregate totals keyed by each value in the array. You can turn this into a one-liner if you only need to count one value:
_.countBy(['foo', 'foo', 'bar'])['foo']; // 2
This also works fine on arrays of numbers. The one-liner for your example would be:
_.countBy([1, 2, 3, 5, 2, 8, 9, 2])[2]; // 3
Weirdest way I can think of doing this is:
(a.length-(' '+a.join(' ')+' ').split(' '+n+' ').join(' ').match(/ /g).length)+1
Where:
a is the array
n is the number to count in the array
My suggestion, use a while or for loop ;-)
Not using a loop usually means handing the process over to some method that does use a loop.
Here is a way our loop hating coder can satisfy his loathing, at a price:
var a=[1, 2, 3, 5, 2, 8, 9, 2];
alert(String(a).replace(/[^2]+/g,'').length);
/* returned value: (Number)
3
*/
You can also repeatedly call indexOf, if it is available as an array method, and move the search pointer each time.
This does not create a new array, and the loop is faster than a forEach or filter.
It could make a difference if you have a million members to look at.
function countItems(arr, what){
var count= 0, i;
while((i= arr.indexOf(what, i))!= -1){
++count;
++i;
}
return count
}
countItems(a,2)
/* returned value: (Number)
3
*/
I'm a begin fan of js array's reduce function.
const myArray =[1, 2, 3, 5, 2, 8, 9, 2];
const count = myArray.reduce((count, num) => num === 2 ? count + 1 : count, 0)
In fact if you really want to get fancy you can create a count function on the Array prototype. Then you can reuse it.
Array.prototype.count = function(filterMethod) {
return this.reduce((count, item) => filterMethod(item)? count + 1 : count, 0);
}
Then do
const myArray =[1, 2, 3, 5, 2, 8, 9, 2]
const count = myArray.count(x => x==2)
Most of the posted solutions using array functions such as filter are incomplete because they aren't parameterized.
Here goes a solution with which the element to count can be set at run time.
function elementsCount(elementToFind, total, number){
return total += number==elementToFind;
}
var ar = [1, 2, 3, 5, 2, 8, 9, 2];
var elementToFind=2;
var result = ar.reduce(elementsCount.bind(this, elementToFind), 0);
The advantage of this approach is that could easily change the function to count for instance the number of elements greater than X.
You may also declare the reduce function inline
var ar = [1, 2, 3, 5, 2, 8, 9, 2];
var elementToFind=2;
var result = ar.reduce(function (elementToFind, total, number){
return total += number==elementToFind;
}.bind(this, elementToFind), 0);
Really, why would you need map or filter for this?
reduce was "born" for these kind of operations:
[1, 2, 3, 5, 2, 8, 9, 2].reduce( (count,2)=>count+(item==val), 0);
that's it! (if item==val in each iteration, then 1 will be added to the accumulator count, as true will resolve to 1).
As a function:
function countInArray(arr, val) {
return arr.reduce((count,item)=>count+(item==val),0)
}
Or, go ahead and extend your arrays:
Array.prototype.count = function(val) {
return this.reduce((count,item)=>count+(item==val),0)
}
It is better to wrap it into function:
let countNumber = (array,specificNumber) => {
return array.filter(n => n == specificNumber).length
}
countNumber([1,2,3,4,5],3) // returns 1
I use this:
function countElement(array, element) {
let tot = 0;
for(var el of array) {
if(el == element) {
tot++;
}
}
return tot;
}
var arr = ["a", "b", "a", "c", "d", "a", "e", "f", "a"];
console.log(countElement(arr, "a")); // 4
var arrayCount = [1,2,3,2,5,6,2,8];
var co = 0;
function findElement(){
arrayCount.find(function(value, index) {
if(value == 2)
co++;
});
console.log( 'found' + ' ' + co + ' element with value 2');
}
I would do something like that:
var arrayCount = [1,2,3,4,5,6,7,8];
function countarr(){
var dd = 0;
arrayCount.forEach( function(s){
dd++;
});
console.log(dd);
}
I believe what you are looking for is functional approach
const arr = ['a', 'a', 'b', 'g', 'a', 'e'];
const count = arr.filter(elem => elem === 'a').length;
console.log(count); // Prints 3
elem === 'a' is the condition, replace it with your own.
Array.prototype.count = function (v) {
var c = 0;
for (let i = 0; i < this.length; i++) {
if(this[i] === v){
c++;
}
}
return c;
}
var arr = [1, 2, 3, 5, 2, 8, 9, 2];
console.log(arr.count(2)); //3
Solution by recursion
function count(arr, value) {
if (arr.length === 1) {
return arr[0] === value ? 1 : 0;
} else {
return (arr.shift() === value ? 1 : 0) + count(arr, value);
}
}
count([1,2,2,3,4,5,2], 2); // 3
Create a new method for Array class in core level file and use it all over your project.
// say in app.js
Array.prototype.occurrence = function(val) {
return this.filter(e => e === val).length;
}
Use this anywhere in your project -
[1, 2, 4, 5, 2, 7, 2, 9].occurrence(2);
// above line returns 3
Here is a one liner in javascript.
Use map. Find the matching values (v === 2) in the array, returning an array of ones and zeros.
Use Reduce. Add all the values of the array for the total number found.
[1, 2, 3, 5, 2, 8, 9, 2]
.map(function(v) {
return v === 2 ? 1 : 0;
})
.reduce((a, b) => a + b, 0);
The result is 3.
Depending on how you want to run it:
const reduced = (array, val) => { // self explanatory
return array.filter((element) => element === val).length;
}
console.log(reduced([1, 2, 3, 5, 2, 8, 9, 2], 2));
// 3
const reducer = (array) => { // array to set > set.forEach > map.set
const count = new Map();
const values = new Set(array);
values.forEach((element)=> {
count.set(element, array.filter((arrayElement) => arrayElement === element).length);
});
return count;
}
console.log(reducer([1, 2, 3, 5, 2, 8, 9, 2]));
// Map(6) {1 => 1, 2 => 3, 3 => 1, 5 => 1, 8 => 1, …}
You can use built-in function Array.filter()
array.filter(x => x === element).length;
var arr = [1, 2, 3, 5, 2, 8, 9, 2];
// Count how many 2 there are in arr
var count = arr.filter(x => x === 2).length;
console.log(count);
One-liner function
const countBy = (a,f)=>a.reduce((p,v,i,x)=>p+!!f(v,i,x), 0)
countBy([1,2,3,4,5], v=>v%2===0) // 2
There are many ways to find out. I think the easiest way is to use the array filter method which is introduced in es6.
function itemCount(array, item) {
return array.filter(element => element === item).length
}
const myArray = [1,3,5,7,1,2,3,4,5,1,9,0,1]
const items = itemCount(myArray, 1)
console.log(items)
Something a little more generic and modern (in 2022):
import {pipe, count} from 'iter-ops';
const arr = [1, 2, 3, 5, 2, 8, 9, 2];
const n = pipe(arr, count(a => a === 2)).first; //=> 3
What's good about this:
It counts without creating a new array, so it is memory-efficient
It works the same for any Iterable and AsyncIterable
Another approach using RegExp
const list = [1, 2, 3, 5, 2, 8, 9, 2]
const d = 2;
const counter = (`${list.join()},`.match(new RegExp(`${d}\\,`, 'g')) || []).length
console.log(counter)
The Steps follows as below
Join the string using a comma Remember to append ',' after joining so as not to have incorrect values when value to be matched is at the end of the array
Match the number of occurrence of a combination between the digit and comma
Get length of matched items
I believe you can use the new Set array method of JavaScript to have unique values.
Example:
var arr = [1, 2, 3, 5, 2, 8, 9, 2]
var set = new Set(arr);
console.log(set);
// 1,2,3,5,8,9 . We get unique values as output.
You can use length property in JavaScript array:
var myarray = [];
var count = myarray.length;//return 0
myarray = [1,2];
count = myarray.length;//return 2

Categories

Resources