So basically I have a couple of numbers that come out as HEX values in the form of "3FF0000000000000" and I want to get float values of out these, pretty much like in here So in this particular case I'd expect "20.000000000000000" as a result - which I'll later trim to only 5 decimals, but that should be easy enough.
I've tried a couple of solutions but unfortunately I know too little about conversions (and javascript aswell) to know exactly what I might be doing wrong.
The latest try looks something like this:
const hexToFloat64 = (hex) => {
var int32 = [],
float64;
if (hex.length > 4) {
var high = hex.substr(0, 8),
low = hex.substr(8, 8);
int32.push(parseInt(high, 16), parseInt(low, 16));
}
var uint32 = new Uint32Array(int32);
float64 = new Float64Array(uint32.buffer);
var returnValue = float64[0];
return returnValue;
};
Much obliged!
This is NOT an answer to your exact problem. It IS a solution to decode the hex. Thats all i am doing here. I have no context to solve your problem.
function convHexStringToString(ss) {
// ss length must be even (or 0) when passed to this function
var s = "";
var p;
if (ss.length > 0) {
if (ss.length % 2 == 0) {
var l = Math.floor(ss.length / 2); // floor must never have to do work
for (var i = 0; i < l; i++) {
var i2 = i * 2;
if (ss.charAt(i2) != "0") {
p = ss.charAt(i2) + ss.charAt((i2) + 1);
}
else {
p = ss.charAt((i2) + 1);
}
d = parseInt(p,16);
s += String.fromCharCode(d);
}
}
}
return s;
}
Related
I am trying to reverse a string. I am aware of .reverse function and other methods in Js to do so, but i wanted to do it this two-pointer method.
The problem is the string is not getting updated. Is there anything i am not aware of strings. Whats wrong here ?
function reverseString(s) {
let lengthOfStr = 0;
if ((s.length - 1) % 2 == 0) {
lengthOfStr = (s.length - 1) / 2
} else {
lengthOfStr = ((s.length - 1) / 2) + 1;
}
let strLengthLast = s.length - 1;
for (let i = 0; i <= lengthOfStr; i++) {
let pt1 = s[i];
let pt2 = s[strLengthLast];
s[i] = pt2;
s[strLengthLast] = pt1;
console.log('----', s[i], s[strLengthLast]);
strLengthLast--;
}
return s;
}
console.log(reverseString('hello'));
Unlike in C, strings in JavaScript are immutable, so you can't update them by indexing into them. Example:
let s = 'abc';
s[1] = 'd';
console.log(s); // prints abc, not adc
You'd need to do something more long-winded in place of s[i] = pt2;, like s = s.substring(0, i) + pt2 + s.substring(i + 1);, and similarly for s[strLengthLast] = pt1; (or combine them into one expression with 3 calls to substring).
I'm not sure why it doesnt update the string, but if you handle the replacement as an array/list it works as follows:
function reverseString(s) {
let lengthOfStr = 0;
sSplit = s.split("");
if ((s.length - 1) % 2 === 0) {
lengthOfStr = (s.length - 1) / 2
}
else {
lengthOfStr = ((s.length - 1) / 2) + 1;
}
let strLengthLast = s.length - 1;
for (let i = 0; i <= lengthOfStr; i++) {
let pt1 = sSplit[i];
let pt2 = sSplit[strLengthLast];
sSplit[i] = pt2;
sSplit[strLengthLast] = pt1;
console.log('----', sSplit[i], sSplit[strLengthLast],sSplit);
strLengthLast--;
}
return sSplit.join("");
}
console.log(reverseString('Hello'));
returns: Hello => olleH
As covered in comment, answers and documentation, strings are immutable in JavaScript.
The ability to apparently assign a property value to a primitive string value results from early JavaScript engine design that temporarily created a String object from primitive strings when calling a String.prototype method on the primitive. While assigning a property to the temporary object didn't error, it was useless since the object was discarded between calling the String method and resuming execution of user code.
The good news is that this has been fixed. Putting
"use strict";
at the beginning of a JavaScript file or function body causes the compiler to generate a syntax error that primitive string "properties" are read-only.
There are many ways of writing a function to reverse strings without calling String.prototype.reverse. Here's another example
function strReverse(str) {
"use strict";
let rev = [];
for( let i = str.length; i--;) {
rev.push(str[i]);
}
return rev.join('');
}
console.log( strReverse("Yellow") );
console.log( strReverse("").length);
I tried that way, hopefully might be helpful for someone.
const input = 'hello'; /*input data*/
const inputArray = [...input]; /*convert input data to char array*/
function reverseString(inputArray) {
let i = 0;
let j = inputArray.length -1 ;
while(i < j ) {
const temp = inputArray[i];
inputArray[i] = inputArray[j];
inputArray[j] = temp;
i++;
j--;
}
};
reverseString(inputArray);
console.log(inputArray)
const finalResult = inputArray.join("");
console.log(finalResult);
Thanks.
I have a large text from which I read data according to the scheme. Key words are placed in the "smallArtName" array. The scheme looks like this:
(key word) xxx (cordX|cordY)
I can't convert the string I received to a number. It seems to me that the reason is white space, visible in the terminal in the picture. I tried to use the replace method which works for sample text, but not for my value.
I'm a beginner and I could probably do it simpler, but the code I wrote works, and this is the most important thing for now.
for (i = 0; i < smallArtName.length; i++) {
var n = art.artPrintScreen.indexOf(smallArtName[i]);
if (n > 0) {
var tempString = art.artPrintScreen.substring(n, n + 100);
betweenChar = tempString.indexOf('|');
for (k = betweenChar - 10; k <= betweenChar + 10; k++) {
if (tempString[k] == '(') {
xStart = k;
}
if (tempString[k] == ')') {
yEnd = k;
}
}
cordX = tempString.slice(xStart + 1, betweenChar);
cordY = tempString.slice(betweenChar + 1, yEnd);
strTest = " t est".replace(/\s/g, '')
var cordY2 = cordY.replace(/\s/g, '')
console.log(typeof (cordY))
console.log(cordY2)
console.log(cordY2[0])
console.log(cordY2[1])
console.log(cordY2[2])
console.log(cordY2[3])
console.log(cordY2[4])
console.log(cordY2[5])
console.log(strTest)
var cordYtest = parseInt(cordY2, 10);
console.log(cordYtest)
}
}
You just need to change the regex so that you replace everything except digits and the negative sign - rather than just whitespace. i.e.
change
var cordY2 = cordY.replace(/\s/g, '')
to
var cordY2 = parseInt(cordY.replace(/[^0-9-]/g, ''), 10);
So that the variable cordY2 contains the number you require.
I am making a javascript function that will input a string, and output a "spongebob mocking text"
basically, you input "Hello, this is a message to the world" and you would get "HeLlO, ThIS iS a MeSsAGe tO tHE wORlD"
basically, randomly decide wheather to capitalize a letter or not. I made a function which i thought would do that, but it didn't work. here is the code that I tested in the js console:
function memify(input) { // function called memify()
var il = input.length; // gets the length of the input
var newinput = input; // creates a new variable that will be changed from input.
for (var i=0;i>il;i++) {
var rng = Math.floor((Math.random()*2)); // random number between 0 and 1. 0 = upper 1 = lower
if (rng === 0) {
newinput.charAt(i).toUpperCase();
}
else {
newinput.charAt(i).toLowerCase();
}
}
return newinput;
}
var text = prompt();
var textmeme = memify(text);
alert(textmeme);
Why is this not working? Do I have an error in my code? Any help will be greatly appreciated.
When you do
newinput.charAt(i).toUpperCase();
you're creating a new uppercase character, but you aren't doing anything with it; it's just an unused expression, so there's no visible change. Primitives (including strings) are immutable - you should explicitly reassign a string to something else (eg newString += newinput.charAt(i).toUpperCase();) to see an effect.
You also need to use
for (var i = 0; i < il; i++) {
// ^
instead of
for (var i = 0; i > il; i++) {
// ^
else, no iterations will run at all.
function memify(input) { // function called memify()
var il = input.length; // gets the length of the input
let changedStr = '';
for (var i = 0; i < il; i++) {
var rng = Math.floor((Math.random() * 2)); // random number between 0 and 1. 0 = upper 1 = lower
if (rng === 0) {
changedStr += input.charAt(i).toUpperCase();
} else {
changedStr += input.charAt(i).toLowerCase();
}
}
return changedStr;
}
var text = prompt();
var textmeme = memify(text);
console.log(textmeme);
Another option, using .map, which looks much cleaner IMO:
const memify = input => [...input]
.map(char => Math.random() < 0.5 ? char.toUpperCase() : char.toLowerCase())
.join('');
console.log(memify(prompt()));
Or more concise, safer and generally better solution :). It does not require for loop, checking length of string and other error prone stuff.
function memify(input) {
var rng = () => Math.random() > 0.5;
var res = input.split('').map( letter =>
rng() ? letter.toUpperCase() : letter.toLowerCase()
).join('');
return res;
}
var textmeme = memify("Hello World");
console.log(textmeme);
Please up-vote if it was helpful :)
I have a page with a grid where user's numbers get saved. It has a following pattern - every number ends with 3 digits after comma. It doesn't look nice, when for example user's input is
123,450
123,670
123,890
It's much better to have just 2 numbers after comma, because last 0 is absolutely meaningless and redundant.
The way it still should have 3 digits is only if at least one element in an array doesn't end up with 0
For example:
123,455
123,450
123,560
In this case 1st element of the array has the last digit not equal to 0 and hence all the elements should have 3 digits. The same story with 2 or 1 zeros
Zeros are redundant:
123,30
123,40
123,50
Zeros are necessary:
123,35
123,40
123,50
The question is how can I implement it programatically? I've started like this:
var zeros2Remove = 0;
numInArray.forEach(function(item, index, numInArray)
{
var threeDigitsAfterComma = item.substring(item.indexOf(',') + 1);
for(var j = 2; j <= 0; j--)
{
if(threeDigitsAfterComma[j] == 0)
{
zeros2Remove =+ 1;
}
else //have no idea what to do..
}
})
Well in my implementation I don't know how to do it since I have to iterate through every element but break it if at least 1 number has a last digit equal to zero.. In order to do that I have to break outer loop, but don't know how and I'm absolutely sure that I don't have to...
I think the following code what you are looking for exactly , please manipulate numbers and see the changes :
var arr = ["111.3030", "2232.0022", "3.001000", "4","558.0200","55.00003000000"];
var map = arr.map(function(a) {
if (a % 1 === 0) {
var res = "1";
} else {
var lastNumman = a.toString().split('').pop();
if (lastNumman == 0) {
var m = parseFloat(a);
var res = (m + "").split(".")[1].length;
} else {
var m = a.split(".")[1].length;
var res = m;
}
}
return res;
})
var maxNum = map.reduce(function(a, b) {
return Math.max(a, b);
});
arr.forEach(function(el) {
console.log(Number.parseFloat(el).toFixed(maxNum));
});
According to MDN,
There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behavior, the forEach() method is the wrong tool. Use a plain loop or for...of instead.
If you convert your forEach loop to a for loop, you can break out of it with a label and break statement:
// unrelated example
let i;
let j;
outerLoop:
for (i = 2; i < 100; ++i) {
innerLoop:
for (j = 2; j < 100; ++j) {
// brute-force prime factorization
if (i * j === 2183) { break outerLoop; }
}
}
console.log(i, j);
I gave you an unrelated example because your problem doesn't need nested loops at all. You can find the number of trailing zeroes in a string with a regular expression:
function getTrailingZeroes (str) {
return str.match(/0{0,2}$/)[0].length;
}
str.match(/0{0,2}$/) finds between 0 and 2 zeroes at the end of str and returns them as a string in a one-element array. The length of that string is the number of characters you can remove from str. You can make one pass over your array of number-strings, breaking out when necessary, and use Array.map as a separate truncation loop:
function getShortenedNumbers (numInArray) {
let zeroesToRemove = Infinity;
for (const str of numInArray) {
let candidate = getTrailingZeroes(str);
zeroesToRemove = Math.min(zeroesToRemove, candidate);
if (zeroesToRemove === 0) break;
}
return numInArray.map(str => str.substring(0, str.length - zeroesToRemove);
}
All together:
function getTrailingZeroes (str) {
return str.match(/0{0,2}$/)[0].length;
}
function getShortenedNumbers (numInArray) {
let zeroesToRemove = Infinity;
for (const str of numInArray) {
let candidate = getTrailingZeroes(str);
zeroesToRemove = Math.min(zeroesToRemove, candidate);
if (zeroesToRemove === 0) break;
}
return numInArray.map(str => str.substring(0, str.length - zeroesToRemove));
}
console.log(getShortenedNumbers(['123,450', '123,670', '123,890']));
console.log(getShortenedNumbers(['123,455', '123,450', '123,560']));
This solution might seem a little cumbersome but it should work for all possible scenarios. It should be easy enough to make always return a minimal number of decimals places/leading zeros.
I hope it helps.
// Define any array
const firstArray = [
'123,4350',
'123,64470',
'123,8112390',
]
const oneOfOfYourArrays = [
'123,30',
'123,40',
'123,50',
]
// Converts 123,45 to 123.45
function stringNumberToFloat(stringNumber) {
return parseFloat(stringNumber.replace(',', '.'))
}
// For 123.45 you get 2
function getNumberOfDecimals(number) {
return number.split('.')[1].length;
}
// This is a hacky way how to remove traling zeros
function removeTralingZeros(stringNumber) {
return stringNumberToFloat(stringNumber).toString()
}
// Sorts numbers in array by number of their decimals
function byNumberOfValidDecimals(a, b) {
const decimalsA = getNumberOfDecimals(a)
const decimalsB = getNumberOfDecimals(b)
return decimalsB - decimalsA
}
// THIS IS THE FINAL SOLUTION
function normalizeDecimalPlaces(targetArray) {
const processedArray = targetArray
.map(removeTralingZeros) // We want to remove trailing zeros
.sort(byNumberOfValidDecimals) // Sort from highest to lowest by number of valid decimals
const maxNumberOfDecimals = processedArray[0].split('.')[1].length
return targetArray.map((stringNumber) => stringNumberToFloat(stringNumber).toFixed(maxNumberOfDecimals))
}
console.log('normalizedFirstArray', normalizeDecimalPlaces(firstArray))
console.log('normalizedOneOfOfYourArrays', normalizeDecimalPlaces(oneOfOfYourArrays))
Try this
function removeZeros(group) {
var maxLength = 0;
var newGroup = [];
for(var x in group) {
var str = group[x].toString().split('.')[1];
if(str.length > maxLength) maxLength = str.length;
}
for(var y in group) {
var str = group[y].toString();
var substr = str.split('.')[1];
if(substr.length < maxLength) {
for(var i = 0; i < (maxLength - substr.length); i++)
str += '0';
}
newGroup.push(str);
}
return newGroup;
}
Try it on jsfiddle: https://jsfiddle.net/32sdvzn1/1/
My script checks the length of every number decimal part, remember that JavaScript removes the last zeros in a decimal number, so 3.10 would be 3.1, so the length is less when there is a number with zeros in the end, in this case we just add a zero to the number.
Update
I've updated the script, the new version adds as much zeros as the different between the max decimal length and the decimal length of the analyzed number.
Example
We have: 3.11, 3.1423, 3.1
The max length would be: 4 (1423)
maxLenght (4) - length of .11 (2) = 2
We add 2 zeros to 3.11, that will become 3.1100
I think you can start out assuming you will remove two extra zeros, and loop through your array looking for digits in the last two places. With the commas, I'm assuming your numArray elements are strings, all starting with the same length.
var numArray = ['123,000', '456,100', '789,110'];
var removeTwo = true, removeOne = true;
for (var i = 0; i < numArray.length; i++) {
if (numArray[i][6] !== '0') { removeTwo = false; removeOne = false; }
if (numArray[i][5] !== '0') { removeTwo = false; }
}
// now loop to do the actual removal
for (var i = 0; i < numArray.length; i++) {
if (removeTwo) {
numArray[i] = numArray[i].substr(0, 5);
} else if (removeOne) {
numArray[i] = numArray[i].substr(0, 6);
}
}
This question already has answers here:
Repeat String - Javascript [duplicate]
(30 answers)
Closed 7 years ago.
I need to understand how Javascript handles the new string object just like in the C# code below
var UpperBound = 14;
for (int i = 0; i < UpperBound; i++) {
Console.WriteLine(new string('*', i));
}
Console.ReadLine();
This was how i did it in Javascript:
var upperBound = 14;
for(var i=0;i<upperBound;i++){
console.log(new string("*", i));
}
Am a newbie in programming and i started off with javascript so if i appear dumb by asking this question pls pardon and assist me by explaining.. thanks
There is no equivalent for new string("*", i) in JS. You need to do repetition yourself.
A handy hack is Array(i + 1).join("*"), but it is not very efficient I don't think, as it needs to construct the array. The best way is probably to loop and concatenate.
Your code is good except for this part:
new string("*", i)
It is incorrect syntax for JS. You need to create string another way.
That's how you should create a string with repeating character in JavaScript.
I should note that String.prototype.repeat is a part of ECMAScript 6.
var upperBound = 14;
for(var i=0;i<upperBound;i++)
{
document.write('*'.repeat(i));
document.write("<br/>");
}
Before it, you should use another approach like making this string manually in a for-loop like this:
function repeatString(ch, t)
{
var res = '';
for (var i = 0; i < t; i++) res += ch;
return res;
}
var upperBound = 14;
for(var i=0;i<upperBound;i++)
{
document.write(repeatString('*', i));
document.write("<br/>");
}
There are some other approaches and hacks. You can read this StackOverflow topic on it.
I suggest you to read a good tutorial on JavaScript before trying to write it.
C# and JavaScript are very different languages in all terms. You cannot just take a C# code, change a syntax and think that it will work.
I would like to combine two solutions, so (the best option is to use es6-shim) here is a polyfill (borrowed from here)
if (!String.prototype.repeat) {
String.prototype.repeat = function(count) {
'use strict';
if (this == null) {
throw new TypeError('can\'t convert ' + this + ' to object');
}
var str = '' + this;
count = +count;
if (count != count) {
count = 0;
}
if (count < 0) {
throw new RangeError('repeat count must be non-negative');
}
if (count == Infinity) {
throw new RangeError('repeat count must be less than infinity');
}
count = Math.floor(count);
if (str.length == 0 || count == 0) {
return '';
}
// Ensuring count is a 31-bit integer allows us to heavily optimize the
// main part. But anyway, most current (August 2014) browsers can't handle
// strings 1 << 28 chars or longer, so:
if (str.length * count >= 1 << 28) {
throw new RangeError('repeat count must not overflow maximum string size');
}
var rpt = '';
for (;;) {
if ((count & 1) == 1) {
rpt += str;
}
count >>>= 1;
if (count == 0) {
break;
}
str += str;
}
return rpt;
}
}
And the usage:
var upperBound = 14;
for(var i=0;i<upperBound;i++){
console.log("*".repeat(i));
}