convert string into array of integers - javascript

I want to convert the following string '14 2' into an array of two integers.
How can I do it ?

A quick one for modern browsers:
'14 2'.split(' ').map(Number);
// [14, 2]`

You can .split() to get an array of strings, then loop through to convert them to numbers, like this:
var myArray = "14 2".split(" ");
for(var i=0; i<myArray.length; i++) { myArray[i] = +myArray[i]; }
//use myArray, it's an array of numbers
The +myArray[i] is just a quick way to do the number conversion, if you're sure they're integers you can just do:
for(var i=0; i<myArray.length; i++) { myArray[i] = parseInt(myArray[i], 10); }

SO...older thread, I know, but...
EDIT
#RoccoMusolino had a nice catch; here's an alternative:
TL;DR:
const intArray = [...("5 6 7 69 foo 0".split(' ').filter(i => /\d/g.test(i)))]
WRONG: "5 6 note this foo".split(" ").map(Number).filter(Boolean); // [5, 6]
There is a subtle flaw in the more elegant solutions listed here, specifically #amillara and #Marcus' otherwise beautiful answers.
The problem occurs when an element of the string array isn't integer-like, perhaps in a case without validation on an input. For a contrived example...
The problem:
var effedIntArray = "5 6 7 69 foo".split(' ').map(Number); // [5, 6, 7, 69, NaN]
Since you obviously want a PURE int array, that's a problem. Honestly, I didn't catch this until I copy-pasted SO code into my script... :/
The (slightly-less-baller) fix:
var intArray = "5 6 7 69 foo".split(" ").map(Number).filter(Boolean); // [5, 6, 7, 69]
So, now even when you have crap int string, your output is a pure integer array. The others are really sexy in most cases, but I did want to offer my mostly rambly w'actually. It is still a one-liner though, to my credit...
Hope it saves someone time!

var result = "14 2".split(" ").map(function(x){return parseInt(x)});

An alternative to Tushar Gupta answer would be :
'14 2'.split(' ').map(x=>+x);
// [14, 2]`
In code golf you save 1 character.
Here the "+" is "unary plus" operator, works like parseInt.

First split the string on spaces:
var result = '14 2'.split(' ');
Then convert the result array of strings into integers:
for (var i in result) {
result[i] = parseInt(result[i], 10);
}

The point against parseInt-approach:
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

If the numbers can be separated by more than one space, it is safest to split the string on one or more consecutive whitespace characters (which includes tabs and regular spaces). With a regular expression, this would be \s+.
You can then map each element using the Number function to convert it. Note that parseInt will not work (i.e. arr.map(parseInt)) because map passes three arguments to the mapping function: the element, the index, and the original array. parseInt accepts the base or radix as the second parameter, so it will end up taking the index as the base, often resulting in many NaNs in the result. However, Number ignores any arguments other than the first, so it works directly.
const str = '1\t\t2 3 4';
const result = str.split(/\s+/).map(Number); //[1,2,3,4]
To remove elements that are not numbers, Array#filter can be used in conjunction with isNaN.
const str = '1\t\t2 3 ab 4 c';
const result = str.split(/\s+/).map(Number).filter(x => !isNaN(x)); //[1,2,3,4]
You could also use an anonymous function for the mapping callback with the unary plus operator to convert each element to a number.
const str = '1\t\t2 3 4';
const result = str.split(/\s+/).map(x => +x); //[1,2,3,4]
With an anonymous function for the callback, you can decide what parameters to use, so parseInt can also work.
const str = '1\t\t2 3 4';
const result = str.split(/\s+/).map(x => parseInt(x)); //[1,2,3,4]

Just for fun I thought I'd throw a forEach(f()) solution in too.
var a=[];
"14 2".split(" ").forEach(function(e){a.push(parseInt(e,10))});
// a = [14,2]

let idsArray = ids.split(',').map((x) => parseInt(x));

Better one line solution:
var answerInt = [];
var answerString = "1 2 3 4";
answerString.split(' ').forEach(function (item) {
answerInt.push(parseInt(item))
});

us the split function:
var splitresult = "14 2".split(" ");

Related

Slice method indexing issue in Javascript

I have a string as an input in the form; lets say "1,5;6,10". Now, I want to compare the number at position 1 and 3 .i.e.(1 & 6). Whichever one is largest the number right to it would be printed. In this case the number 10 would be printed as 1 < 6.
Let the input is,
const customer_demand ="1,5;6,10";
I want to procced with slice() method and separate 1 and 6 with:
const number1 = customer_demand.slice(0, 1); // 1
const number2 = customer_demand.slice(4, 5); // 6
and compare the resultants with if & else. But there may be a case when the third number is two digit like:
const customer_demand ="1,5;16,10";
my slice() method index would go offset. What can I do in this regard? I hope I have made myself clear, if not please leave a comment. Thanks
In your case it's better to use split:
const customer_demand ="1,5;16,10";
const number1 = customer_demand.split(";")[0].split(",")[0]; // 1
const number2 = customer_demand.split(";")[1].split(",")[0]; // 16
Also if you want them to be Numbers don't forget to cast it using parseInt.
The solution, use split. Here's an example
const customer_demand ="1,5;16,10";
function parseNumbers(string){
return string.split(";") //returns stuff like ["1,5", "16,10"]
.map(axis=>
axis.split(",") //["1", "5"]
.map(n=>parseInt(n)) //[1,5]
)
}
//example usage
const parsedDemand=parseNumbers(customer_demand)
const [number1,number2,number3,number4]=parsedDemand
console.log(parsedDemand)
Make your life easier and break up your strings into managable arrays. Here is an example of when you don't know how many sets of numbers to compare ahead of time.
const customer_demand ="1,5;16,10";
// the following should also work for data like: "1,3,4,7;1,44;100"
let answers = [];
customer_demand.split(";").forEach( set => {
let setitems = set.split(",");
let biggest = setitems.reduce(function(a, b) {
return Math.max(Number(a), Number(b));
});
answers.push(biggest)
});
// answers is now an array - each item is the biggest number of that set. In your example it would be [5,16]

In Node/Javascript, how do I map cardinality from string to int?

For example, I have user input any string: "1st", "2nd", "third", "fourth", "fifth", "9999th", etc. These are just examples, the user can input any string.
I want to map this to integer cardinality:
"1st" -> 0
"2nd" -> 1
"third" -> 2
"fourth" -> 3
"fifth" -> 4
"9999th" -> 9998
So I need some kind of function where:
function mapCardinality(input: string): number{
let numberResult:number = ??
return numberREesult;
}
and I can call it like this:
console.log(
mapCardinality("1st"), // print 0
mapCardinality("2nd"), // print 1
mapCardinality("third"), // print 2
mapCardinality("fourth"), // print 3
mapCardinality("fifth"), // print 4
mapCardinality("9999th") // print 9998
);
Just look it up in an array or parse it as number:
const mapCardinality = c => {
const pos = ["1st", "2nd", "third", "fourth", "fifth"].indexOf(c);
return pos === -1 ? parseInt(c, 10) - 1 : pos;
};
I'd first ask what are the suffixes for all of the inputs?
'nd', 'rd', 'st', 'th' (most numbers)
If they enter an integer with the above prefixes then you could write the following function:
const getInteger = input => input.slice(0, -2);
const num = getInteger('999th');
console.log(num); // prints "999"
If they enter the elongated variant, it becomes much more complex, especially when it comes to typos, lack of spaces, etc. One way could be to map single digit words ('one', 'two', etc), tens ('ten', 'twenty', etc'), hundreds, thousands, and so on instead of every number imaginable. I would then parse and find matching words to give a result. That being said it is still limiting. I would strongly suggest limiting user input formats. Why can't the user input an integer?
const cardinalDictionary = {
'zero': 0,
'one': 1,
...,
'twenty',
...,
'hundred': 100,
'thousand': 1000,
};

JavaScript - Matching alphanumeric patterns with RegExp

I'm new to RegExp and to JS in general (Coming from Python), so this might be an easy question:
I'm trying to code an algebraic calculator in Javascript that receives an algebraic equation as a string, e.g.,
string = 'x^2 + 30x -12 = 4x^2 - 12x + 30';
The algorithm is already able to break the string in a single list, with all values on the right side multiplied by -1 so I can equate it all to 0, however, one of the steps to solve the equation involves creating a hashtable/dictionary, having the variable as key.
The string above results in a list eq:
eq = ['x^2', '+30x', '-12', '-4x^2', '+12x', '-30'];
I'm currently planning on iterating through this list, and using RegExp to identify both variables and the respective multiplier, so I can create a hashTable/Dictionary that will allow me to simplify the equation, such as this one:
hashTable = {
'x^2': [1, -4],
'x': [30, 12],
' ': [-12]
}
I plan on using some kind of for loop to iter through the array, and applying a match on each string to get the values I need, but I'm quite frankly, stumped.
I have already used RegExp to separate the string into the individual parts of the equation and to remove eventual spaces, but I can't imagine a way to separate -4 from x^2 in '-4x^2'.
You can try this
(-?\d+)x\^\d+.
When you execute match function :
var res = "-4x^2".match(/(-?\d+)x\^\d+/)
You will get res as an array : [ "-4x^2", "-4" ]
You have your '-4' in res[1].
By adding another group on the second \d+ (numeric char), you can retrieve the x power.
var res = "-4x^2".match(/(-?\d+)x\^(\d+)/) //res = [ "-4x^2", "-4", "2" ]
Hope it helps
If you know that the LHS of the hashtable is going to be at the end of the string. Lets say '4x', x is at the end or '-4x^2' where x^2 is at end, then we can get the number of the expression:
var exp = '-4x^2'
exp.split('x^2')[0] // will return -4
I hope this is what you were looking for.
function splitTerm(term) {
var regex = /([+-]?)([0-9]*)?([a-z](\^[0-9]+)?)?/
var match = regex.exec(term);
return {
constant: parseInt((match[1] || '') + (match[2] || 1)),
variable: match[3]
}
}
splitTerm('x^2'); // => {constant: 1, variable: "x^2"}
splitTerm('+30x'); // => {constant: 30, variable: "x"}
splitTerm('-12'); // => {constant: -12, variable: undefined}
Additionally, these tool may help you analyze and understand regular expressions:
https://regexper.com/
https://regex101.com/
http://rick.measham.id.au/paste/explain.pl

What's the best way to seperate the first line of a string from the rest in JS?

In Python, there was good old firstline, rest = text.split("\n", 1). After some painful discovery, I realized that JavaScript gives a different meaning to the limit property, and returns that many "splits" (1 means it returns only the first line, 2 returns only the first two lines, and so forth).
What's the best way to get what I wanted? Do I have to make do with slice and indexOf?
Probably the most efficient way:
function getFirstLine(text) {
var index = text.indexOf("\n");
if (index === -1) index = undefined;
return text.substring(0, index);
}
Then:
// "Some string goes here"
console.log(getFirstLine("Some string goes here\nSome more string\nAnd more\n\nMore"));
// "asdfasdfasdf"
console.log(getFirstLine("asdfasdfasdf"));
Edit:
function newSplit(text, lineSplit) {
if (lineSplit <= 0) return null;
var index = -1;
for (var i = 0; i < lineSplit; i++) {
index = text.indexOf("\n", index) + 1;
if (index === 0) return null;
}
return { 0: text.substring(0, index - 1), 1: text.substring(index) }
}
Output:
newSplit("someline\nasdfasdf\ntest", 1);
> Object {0: "someline", 1: "asdfasdf↵test"}
newSplit("someline\nasdfasdf\ntest", 2);
> Object {0: "someline↵asdfasdf", 1: "test"}
newSplit("someline\nasdfasdf\ntest", 0);
> null
newSplit("someline\nasdfasdf\ntest", 3);
> null
You can use shift to remove the first item from an array.
var lines = text.split("\n"); // split all lines into array
var firstline = lines.shift(); // read and remove first line
var rest = lines.join("\n"); // re-join the remaining lines
This is perhaps idomatically closest to what you do in Python, but it's hardly the most efficient approach.
Another possibility, using a regex with String.match and Array.slice
Javascript
var text = "Simple Simon met a Pieman,\ngoing to a fair.\nSaid simple Simon to the Pieman,\n\n\"Let me taste your ware.\"";
console.log((text.match(/^([\s\S]*?)\n([\s\S]*)$/) || []).slice(1, 3));
Output
["Simple Simon met a Pieman,", "going to a fair.↵Said simple Simon to the Pieman,↵↵"Let me taste your ware.""]
On jsfiddle
The RegExp.exec() method will do the trick:
//some multiline text
var text='line1\nline2'
//exec puts the first line in an array
var firstline=/.*/.exec(text)[0]
REPL Output:
>>> firstline
line1
When the regex is saved as an object with global and multiline flags, exec can be used to step through each line in a loop, manually shown here in the jsc REPL:
>>> var reg = /^.*/gm
>>> var text='line1\nline2'
>>> reg.exec(text)
line1
>>> reg.exec(text)
line2
>>> reg.exec(text)
null

Is there "0b" or something similar to represent a binary number in Javascript

I know that 0x is a prefix for hexadecimal numbers in Javascript. For example, 0xFF stands for the number 255.
Is there something similar for binary numbers ? I would expect 0b1111 to represent the number 15, but this doesn't work for me.
Update:
Newer versions of JavaScript -- specifically ECMAScript 6 -- have added support for binary (prefix 0b), octal (prefix 0o) and hexadecimal (prefix: 0x) numeric literals:
var bin = 0b1111; // bin will be set to 15
var oct = 0o17; // oct will be set to 15
var oxx = 017; // oxx will be set to 15
var hex = 0xF; // hex will be set to 15
// note: bB oO xX are all valid
This feature is already available in Firefox and Chrome. It's not currently supported in IE, but apparently will be when Spartan arrives.
(Thanks to Semicolon's comment and urish's answer for pointing this out.)
Original Answer:
No, there isn't an equivalent for binary numbers. JavaScript only supports numeric literals in decimal (no prefix), hexadecimal (prefix 0x) and octal (prefix 0) formats.
One possible alternative is to pass a binary string to the parseInt method along with the radix:
var foo = parseInt('1111', 2); // foo will be set to 15
In ECMASCript 6 this will be supported as a part of the language, i.e. 0b1111 === 15 is true. You can also use an uppercase B (e.g. 0B1111).
Look for NumericLiterals in the ES6 Spec.
I know that people says that extending the prototypes is not a good idea, but been your script...
I do it this way:
Object.defineProperty(
Number.prototype, 'b', {
set:function(){
return false;
},
get:function(){
return parseInt(this, 2);
}
}
);
100..b // returns 4
11111111..b // returns 511
10..b+1 // returns 3
// and so on
If your primary concern is display rather than coding, there's a built-in conversion system you can use:
var num = 255;
document.writeln(num.toString(16)); // Outputs: "ff"
document.writeln(num.toString(8)); // Outputs: "377"
document.writeln(num.toString(2)); // Outputs: "11111111"
Ref: MDN on Number.prototype.toString
As far as I know it is not possible to use a binary denoter in Javascript. I have three solutions for you, all of which have their issues. I think alternative 3 is the most "good looking" for readability, and it is possibly much faster than the rest - except for it's initial run time cost. The problem is it only supports values up to 255.
Alternative 1: "00001111".b()
String.prototype.b = function() { return parseInt(this,2); }
Alternative 2: b("00001111")
function b(i) { if(typeof i=='string') return parseInt(i,2); throw "Expects string"; }
Alternative 3: b00001111
This version allows you to type either 8 digit binary b00000000, 4 digit b0000 and variable digits b0. That is b01 is illegal, you have to use b0001 or b1.
String.prototype.lpad = function(padString, length) {
var str = this;
while (str.length < length)
str = padString + str;
return str;
}
for(var i = 0; i < 256; i++)
window['b' + i.toString(2)] = window['b' + i.toString(2).lpad('0', 8)] = window['b' + i.toString(2).lpad('0', 4)] = i;
May be this will usefull:
var bin = 1111;
var dec = parseInt(bin, 2);
// 15
No, but you can use parseInt and optionally omit the quotes.
parseInt(110, 2); // this is 6
parseInt("110", 2); // this is also 6
The only disadvantage of omitting the quotes is that, for very large numbers, you will overflow faster:
parseInt(10000000000000000000000, 2); // this gives 1
parseInt("10000000000000000000000", 2); // this gives 4194304
I know this does not actually answer the asked Q (which was already answered several times) as is, however I suggest that you (or others interested in this subject) consider the fact that the most readable & backwards/future/cross browser-compatible way would be to just use the hex representation.
From the phrasing of the Q it would seem that you are only talking about using binary literals in your code and not processing of binary representations of numeric values (for which parstInt is the way to go).
I doubt that there are many programmers that need to handle binary numbers that are not familiar with the mapping of 0-F to 0000-1111.
so basically make groups of four and use hex notation.
so instead of writing 101000000010 you would use 0xA02 which has exactly the same meaning and is far more readable and less less likely to have errors.
Just consider readability, Try comparing which of those is bigger:
10001000000010010 or 1001000000010010
and what if I write them like this:
0x11012 or 0x9012
Convert binary strings to numbers and visa-versa.
var b = function(n) {
if(typeof n === 'string')
return parseInt(n, 2);
else if (typeof n === 'number')
return n.toString(2);
throw "unknown input";
};
Using Number() function works...
// using Number()
var bin = Number('0b1111'); // bin will be set to 15
var oct = Number('0o17'); // oct will be set to 15
var oxx = Number('0xF'); // hex will be set to 15
// making function convTo
const convTo = (prefix,n) => {
return Number(`${prefix}${n}`) //Here put prefix 0b, 0x and num
}
console.log(bin)
console.log(oct)
console.log(oxx)
// Using convTo function
console.log(convTo('0b',1111))

Categories

Resources