I don't know what is the right question for this.
I want to make this number -800 become [-8,0,0] is anyone can build it
The first thing that I do, is to make the number become a string and using the map function I iterate it becomes an array like this
const number = -800;
const numberString = number.toString();
const arrayString = numberString.split``.map((x) => +x);
console.log(arrayString)
But the result is [ NaN, 8, 0, 0 ]
How to change the NaN and first index 8 become -8 without disturbing the other index. So it becomes [-8, 0, 0]
Is anybody can help me?
Thanks.
Try numberString.match(/-?\d/g) instead of split
const number = -800;
const numberString = number.toString();
const arrayString = numberString.match(/-?\d/g).map(x => +x);
console.log(arrayString)
One possible solution is to just do this operation on the absolute value and, during the map, check if the number was negative (only for the first index).
const number = -800;
const numberString = Math.abs(number).toString();
const arrayString = numberString.split``.map((x, i) => i == 0 && number < 0 ? -x : +x);
console.log(arrayString)
If you're not clear about Regex, you can use Array.from to convert a string to an array number. Then handle the first number based on the sign of original number.
console.log(convertNumberToArray(800));
console.log(convertNumberToArray(-800));
function convertNumberToArray(number){
var result = Array.from(Math.abs(number).toString(), Number);
result[0] *= number <= 0 ? -1 : 1;
return result;
}
Use String#match with regex which matches optional - with the dig it.
var number = -800;
var numberString = number.toString().match(/-?\d/g);
var numberInt = [];
for (var i = 0; i < numberString.length; i++) {
numberInt.push(parseInt(numberString[i]));
}
console.log(numberInt);
Related
I have an integer containing various digits, I want to remove 4th digit from an integer. How can I achieve that ?
Example :
let number = 789012345
Here I want to remove 0
Try this :
// Input
let number = 789012345;
// Convert number into a string
let numberStr = number.toString();
// Replace the 0 with empty string
const res = numberStr.replace(numberStr[3], '');
// Convert string into a number.
console.log(Number(res));
Rohìt Jíndal's answer is excellent. I just want to point out another way you could do this with string.replace and capturing groups.
function removeDigit(input, index) {
let exp = new RegExp(`^(\\d{${index}})(\\d)(.+)$`);
return parseInt(input.toString().replace(exp, '$1$3'));
}
let output = removeDigit(789012345, 3);
console.log(output); // 78912345
In this example, I have created a new RegExp object from a template literal in order to inject the index.
The first capturing group contains all digits up to the desired index. The second contains the digit we want to remove and the third contains the remainder of the string.
We then return an integer parsed from the string combination of only the first and third capturing groups.
You can follow this procedure:
Decide if you want to remove digits by index or by value, the following demo will remove by value, which means it will remove all values that match
Convert the number into a string
Convert the string to an array with Array.from
Use Array#filter to remove target digit(s)
Use Array#join to create a string
Use + to convert to string back into a numeric value
const n = 789012345;
const m = +Array.from( n.toString() ).filter(num => +num !== 0).join("");
console.log( m );
let numberWithoutADigit = removeIthDigitFromNumber(789012345, 4);
function removeIthDigitFromNumber(n, i){
//convert the number n to string as an array of char
let o = (n + '').split('');
//remove the item at the index i (0 based) from the array
o.splice(i, 1);
//rebuilds the string from the array of char and parse the string to return a number
let number = parseInt(o.join(''));
return number;
}
let number = 789012345
let i = 3 // index 3, 4th digit in number
let arr = number.toString().split("").filter((value, index) => index!==i);
// ['7', '8', '9', '1', '2', '3', '4', '5']
let new_number = parseInt(arr.join(""))
// 78912345
console.log(new_number)
let x = 789012345
var nums = [];
let i = 0, temp = 0;
while(x > 1){
nums[i++] = (x % 10);
x = (x - (x % 10)) / 10;
}
var cnt = 0;
for(--i; i >= 0; i--){
if (cnt++ == 3) continue;
temp = temp * 10 + nums[i];
}
Sorry if the title sounds confusing. Basically what I am trying to do is to split a decimal number like this 0.1000 into two part - 1. 0.1 and 000 so I can render them differently with different styles.
Check out this screenshot
All the numbers are represented in strings. The tricky part is that we cannot split the number using number.split('0') since we only want to split at the first zero that appears after a non-zero integer.
Not sure how I can do this.
If I did not misunderstand what you are trying to achieve, you can do it with a regex that only matches unlimited zeros that are at the end of the given string like follows:
function markNumber(num) {
return num.replace( /(0{1,})$/g, '<span>$1</span>')
}
const number = 1.2345670089
let renderStyle1 = ''
let renderStyle2 = ''
const string = String(number) + '.'
const parts = string.split('.')
const decimals = parts[1]
const decimalsArray = Array.from(decimals);
// From MDN: The findIndex() method returns the index of the first element in the array that satisfies the provided testing function. Otherwise -1 is returned.
const firstIndexOfZero = decimalsArray.findIndex(x => x === '0');
// From MDN: The slice() method returns a shallow copy of a portion of an array into a new array object selected from start to end (end not included) where start and end represent the index of items in that array. The original array will not be modified.
if(firstIndexOfZero === -1){
renderStyle1 = parts[0] + parts[1]
} else {
renderStyle1 = parts[0] + decimalsArray.slice(0, firstIndexOfZero).join('') // using .join method to convert array to string without commas
renderStyle2 = decimalsArray.slice(firstIndexOfZero, decimalsArray.length).join('') // using .join method to convert array to string without commas
}
console.log(renderStyle1) // "1234567"
console.log(renderStyle2) // "0089"
Messy, and, probably, can be improved, but this should work:
let re = /(\d*\.[1-9]*?)(0.*)/;
["1000", "1.01", "1.10", "1.000", "1.34043"].map((str) =>
str.split(re).filter((entry) => entry !== "")
);
Here's my regex function
const number = ['0.1000', '2.534300', '1.2000', '1.004334000'];
function split_float(num) {
const reg = /^(\d*\.\d*[^0])(0*)$/g;
const [, ...matches] = [...num.matchAll(reg)][0];
return matches;
}
console.log(number.map(split_float));
here is my answer. It uses split and substring to achieve what you want. Tried it in w3school's tryit editor. Handles all of your data in screenshot pretty well:
function myFunction() {
var str = "0.01200";
var partone = str.split(".")[0];
var temp = str.split(".")[1];
for (var i=0; i<temp.length; i++){
if (temp[i] != 0 && temp[i+1] == 0){
break;
}
}
var parttwo = temp.substring(i+1);
partone = partone + "." + temp.substring(0, i+1);
var res = "partOne = " + partone + " and partTwo = " + parttwo;
document.getElementById("demo").innerHTML = res;
}
Here is the screenshot:
If I have a string a12c56a1b5 then out put should be a13b5c56 as character a is repeated twice so a12 becomes a13
I have tried this:
function stringCompression (str) {
var output = '';
var count = 0;
for (var i = 0; i < str.length; i++) {
count++;
if (str[i] != str[i+1]) {
output += str[i] + count;
count = 0;
}
}
console.log(output); // but it returns `a11121c15161a111b151` instead of `a13b5c56`
}
It is happening because the code is counting the occurrence of each element and appending it, even the numbers in the string.
In this code,
for (var i = 0; i < str.length; i++) {
count++;
if (str[i] != str[i+1]) {
output += str[i] + count;
count = 0;
}
}
in first iteration i = 0, str[i] = 'a' and str[i + 1] = '1' for the given string a12c56a1b5 which are not equal hence, it will generate the output as a1 for first iteration, then a111 for second iteration since str[i] = '1' and str[i + 1] = '2' now, and so on.
We can achieve this by first separating the characters from the count. Assuming, that there would be characters from a-z and A-Z only followed by the count. We can do something like this, str.match(/[a-zA-Z]+/g) to get the characters: ["a", "c", "a", "b"] and str.match(/[0-9]+/g) to get their counts: ["12", "56", "1", "5"], put them in an object one by one and add if it already exists.
Something like this:
function stringCompression(str) {
var characters = str.match(/[a-zA-Z]+/g);
var counts = str.match(/[0-9]+/g);
var countMap = {};
for (var i = 0; i < characters.length; i++) {
if (countMap[characters[i]]) {
countMap[characters[i]] += parseInt(counts[i]);
} else {
countMap[characters[i]] = parseInt(counts[i]);
}
}
var output = Object.keys(countMap)
.map(key => key + countMap[key])
.reduce((a, b) => a + b);
console.log(output);
}
stringCompression('a12c56a1b5')
Using regex to extract word characters and numbers. Keeps an object map res to track and sum up following numbers. sorts and converts back to a string.
As an example, the for-of loop iteration flow with str=a12c56a1b5:
c='a', n='12'
res['a'] = (+n = 12) + ( (res['a'] = undefined)||0 = 0)
or ie: res['a'] = 12 + 0
c='c', n='56'
res['c'] = 56 + 0
c='a', n='1'
res['a'] = 1 + (res['a'] = 12 from iteration 1.) = 13
c='b', n='5'
res['b'] = 5 + 0
thus res = { 'a': 13, 'c': 56, 'b': 5 } after the for-of loop finishes
function stringCompression (str) {
// build object map with sums of following numbers
const res = {}
for(const [,c,n] of str.matchAll(/(\w+)(\d+)/g))
res[c] = +n + (res[c]||0)
// convert object map back to string
output = Object.entries(res)
output.sort(([a],[b])=>a<b ? -1 : a>b ? 1 : 0)
output = output.map(([a,b])=>`${a}${b}`).join('')
console.log(output); // but it returns `a11121c15161a111b151` instead of `a13b5c56`
}
stringCompression('a12c56a1b5')
[,c,n] = [1,2,3] is equivalent to c=2, n=3. It is called destructuring.
matchAll matches on a regex. It's a relatively new shorthand for calling .exec repeatedly to execute a regular expression that collects all the results that the regular expression matches on.
(\w+)(\d+) is a regex for two capture groups,
\w+ is for one or more alpha characters, \d+ is for one or more digits.
for(const [,c,n] of str.matchAll...) is equivalent to:
for each M of str.matchAll...
const c = M[1], n = M[2]`
res[c]||0 is shorthand for:
"give me res[c] if it is truthy (not undefined, null or 0), otherwise give me 0"
+n uses the unary operator + to force an implicit conversion to a number. JavaScript specs for + unary makes it convert to number, since + unary only makes sense with numbers.
It is basically the same as using Number(n) to convert a string to an number.
Conversion back to a string:
Object.entries converts an object {"key":value} to an array in the form of [ [key1, value1], [key2, value2] ]. This allows manipulating the elements of an object like an array.
.sort sorts the array. I destructured the keys to sort on the keys, so "a" "b" "c" are kept in order.
.map takes an array, and "maps" it to another array. In this case I've mapped each [key,value] to a string key+value, and then taking the final mapped array of key+value strings and joined them together to get the final output.
In case it asks you to sort it alphabetically, I added #user120242's sorting code snippet to #saheb's entire answer (in between Object.keys(countMap) and .map(...). That worked for me. I tried using #user120242's whole answer, but it did not pass all the tests since it did not add the repeated letters for longer strings. But #user120242's answer did work. It just need to be sorted alphabetically and it passed all the test cases in HackerRank. I had this question for a coding assessment (called "Better Coding Compression").
P.S. I also removed checking the capital letters from #saheb's code since that wasn't required for my coding challenge.
Here's how mine looked like:
function stringCompression(str) {
var characters = str.match(/[a-zA-Z]+/g);
var counts = str.match(/[0-9]+/g);
var countMap = {};
for (var i = 0; i < characters.length; i++) {
if (countMap[characters[i]]) {
countMap[characters[i]] += parseInt(counts[i]);
} else {
countMap[characters[i]] = parseInt(counts[i]);
}
}
var output = Object.keys(countMap)
.sort(([a],[b])=>a<b ? -1 : a>b ? 1 : 0)
.map(key => key + countMap[key])
.reduce((a, b) => a + b);
console.log(output);
}
stringCompression('a12c56a1b5')
I want to create a javascript function to flip 1's to 0's in a natural number and I'm out of Ideas to achieve this,
Actually, I had a couple of URL's, and I replaced all 0's from a query parameter with 1's and now I no longer know the original parameter value, because there were few 1's in the original parameter value and now both are mixed, so basically I screwed myself,
The only solution for me is to try flipping each 1 to 0 and then 0's to 1's and test each number as the parameter.
This is the parameter value (after replacing 0's with 1's)
11422971
using above input I want to generate numbers as follows and test each of these
11422970
10422971
10422970
01422971
As you can see only 1's and 0's are changing, the change according to binary,
Each position in your string can be one of n characters:
A "0" can be either "0" or "1"
A "1" can be either "0" or "1"
Any other character c can only be c
We can store this in an array of arrays:
"11422971" -> [ ["0", "1"], ["0, "1"], ["4"], ... ]
To transform your string to this format, you can do a split and map:
const chars = "11422971"
.split("")
.map(c => c === "1" || c === "0" ? ["1", "0"] : [ c ]);
Once you got this format, the remaining logic is to create all possible combinations from this array. There are many ways to do so (search for "array combinations" or "permutations"). I've chosen to show a recursive pattern:
const chars = "11422971"
.split("")
.map(c =>
c === "1" || c === "0"
? ["1", "0"]
: [ c ]
);
const perms = ([ xs, ...others ], s = "", ps = []) =>
xs
? ps.concat(...xs.map(x => perms(others, s + x, ps)))
: ps.concat(s);
console.log(perms(chars));
you can do it with a number like a string, and after parse it, something like that
var number= "12551";
number= number.replace("1","0");
The result of number will be "02550"
after that parse number to int
This will generate all permutations.
const generatePermutations = (number) => {
let digits = number.split('');
// find out which digits can be flipped
let digitPositions = digits.reduce((acc, val, i) => {
if (val === '0' || val === '1') acc.push(i);
return acc;
}, []);
// we're going to be taking things in reverse order
digitPositions.reverse();
// how many digits can we flip
let noBits = digitPositions.length;
// number of permutations is 2^noBits i.e. 3 digits means 2^3 = 8 permutations.
let combinations = Math.pow(2, digitPositions.length);
let permutations = [];
// for each permutation
for (var p = 0; p < combinations; p++) {
// take a copy of digits for this permutation
permutations[p] = digits.slice();
// set each of the flippable bits according to the bit positions for this permutation
// i = 3 = 011 in binary
for (var i = 0; i < noBits; i++) {
permutations[p][digitPositions[i]] = '' + ((p >> i) & 1);
}
permutations[p] = permutations[p].join('');
}
return permutations;
};
console.log(generatePermutations('11422970'));
In case your looking for a recursive approach:
function recursive(acc, first, ...rest) {
if(!first) return acc;
if(first == '0' || first == '1') {
var acc0 = acc.map(x => x + '0');
var acc1 = acc.map(x => x + '1');
return recursive([].concat(acc0, acc1), ...rest);
} else {
return recursive(acc.map(x => x + first), ...rest);
}
}
recursive([''], ...'11422971')
// output ["00422970", "10422970", "01422970", "11422970", "00422971", "10422971", "01422971", "11422971"]
This just counts in binary and fills out a template for each value.
function getPossibleValues(str) {
function getResult(n) {
let nIndex = 0;
const strValue = n.toString(2).padStart(nDigits, '0');
return str.replace(rxMatch, () => strValue.charAt(nIndex++));
}
const rxMatch = /[01]/g;
const nDigits = str.length - str.replace(rxMatch, '').length;
const nMax = Math.pow(2, nDigits);
const arrResult = [];
for(let n = 0; n<nMax; n++) {
arrResult.push(getResult(n));
}
return arrResult;
}
console.log(getPossibleValues('11422970'));
Thank you all to respond, you saved my life, btw the approach I used was,
0- convert the number into a string. (so we can perform string operations like split())
1- count the number of 1's in the string (let's say the string is "11422971", so we get three 1's, I used split('1')-1 to count)
2- generate binary of three-digit length,(ie from 000 to 111). three came from step 1.
2- break down the string to single chars, (we'll get
array=['1','1','4','2','2','9','7','1'] )
3- take the first binary number (ie b=0b000)
4- replace first 1 from the character array with the first binary digit of b (ie replace 1 with 0), similarly replace second 1 with the second binary digit of b and so on.
5- we'll get the first combination (ie "00422970")
5- repeat step 3 and 4 for all binary numbers we generated in step 2.
I want to Split a number into its digit (for example 4563 to 4 , 5 , 6 , 3 ) then addiction this digits. (for example: 4+5+6+3=18)
I can write code for 3 digit or 2 digit and ... numbers seperately but I cant write a global code for each number.
so this is my code for 2 digit numbers:
var a = 23
var b = Math.floor(a/10); // 2
var c = a-b*10; // 3
var total = b+c; // 2+3
console.log(total); // 5
and this is my code for 3 digit numbers:
var a = 456
var b = Math.floor(a/100); // 4
var c = a-b*100; // 56
var d = Math.floor(c/10); // 5
var e = c-d*10; // 6
var total = b+d+e; // 4+5+6
console.log(total); // 15
but I cant write a code to work with each number.How can I write a global code for each number?
In modern browsers you can do an array operation like
var num = 4563;
var sum = ('' + num).split('').reduce(function (sum, val) {
return sum + +val
}, 0)
Demo: Fiddle
where you first create an array digits then use reduce to sum up the values in the array
var num = 4563;
var sum = 0;
while(num > 0) {
sum += num % 10;
num = Math.floor(num / 10);
}
console.log(sum);
Do number%10(modulus) and then number/10(divide) till the number is not 0
I hope the following example is useful to you:
var text="12345";
var total=0;
for (i=0;i<text.length;i++)
{
total+= parseInt(text[i]);
}
alert(total);
This solution converts the number to string, splits it into characters and process them in the callback function (prev is the result from the previous call, current is the current element):
var a = 456;
var sum = a.toString().split("").reduce(function(prev, current){
return parseInt(prev) + parseInt(current)
})
Here is how I would approach the problem. The trick I used was to split on the empty string to convert the string to an array and then use reduce on the array.
function digitSum(n) {
// changes the number to a string and splits it into an array
return n.toString().split('').reduce(function(result, b){
return result + parseInt(b);
}, 0);
}
As mentioned by several other posters (hat tip to my commenter), there are several other good answers to this question as well.
Here is my solution using ES6 arrow functions as call back.
- Convert the number into a string.
- Split the string into an array.
- Call the map method on that array.
- Callback function parse each digit to an array.
let number = 65535;
//USING MAP TO RETURN AN ARRAY TO DIGITS
let digits = number.toString()
.split("")
.map(num => parseInt(num));
//OUTPUT TO DOM
digits.forEach(
digit =>
document.querySelector("#out").innerHTML += digit + "<br>"
);
<p id="out"></p>
1) You can cast input number to string, using .toString() method and expand it into array with spread (...) operator
const splitNumber = n => [ ...n.toString() ]
2) Another short way - using recursion-based solution like:
const splitNumber = n => n ? [ ...splitNumber(n/10|0), n%10 ] : []