How does javascript do the comparison? - javascript

I have an object array that gets new values every time a new user is created. I need to do some search based on the person name and then do some operations with it and I implemented a binary search and in my code that I found in the internet but theres something thats bothering me with the search code.
The object looks as follows:
person = {
name: name,
password: password,
cartItems: '',
cartPrice: 0
}
then I push it to an array.
and the binary search code looks as follows:
searchValues(users, value) {
var startIndex = 0,
stopIndex = users.length,
middle = Math.floor((stopIndex + startIndex) / 2);
while(users[middle].name != value && startIndex < stopIndex){
//adjust search area
if (value < users[middle].name) {
stopIndex = middle - 1;
} else if (value > users[middle].name) {
startIndex = middle + 1;
}
//recalculate middle
middle = Math.floor((stopIndex + startIndex) / 2);
}
return (users[middle].name != value) ? -1 : middle;
}
My questions is: How does JavaScript do the comparison between string values, does it convert to ascii? I can understand the code if it was applied to numbers but I'm a bit confused when it comes to strings.
Thank you in advance for anyone willing to help
EDIT: I forgot to mention that i've sorted my array before hand.

The algorithm to compare two strings is simple:
Compare the first character of both strings.
If the first character from the first string is greater (or less) than the other string’s, then the first string is greater (or less) than the second. We’re done.
Otherwise, if both strings’ first characters are the same, compare the second characters the same way.
Repeat until the end of either string.
If both strings end at the same length, then they are equal. Otherwise, the longer string is greater.
reference find more detail here

Related

CTCI Ch.1.2 Check Permutation

Greetings and happy holidays,
My question involves problem "1.2 Check Permutation" from "Cracking The Coding Interview" 6th Ed.
When we compare the two strings, we check for any values in the array that are less than 0. This would indicate different char counts of our two strings. However, shouldn't the comparison be !== 0 instead of < 0? This would catch both over and undercounts of the chars. I didn't see this in the books Errata nor on any related search results.
Below is the provided code solution. (I mainly work in JS, so perhaps I'm reading the code incorrectly)
Many thanks in advance.
boolean permutation(String s, String t) {
if (s.length() != t.length()) {
return false;
}
int[] letters = new int[128];
char[] s_array = s.toCharArray();
for (char c : s_array) {
letters[c]++;
}
for (int i = 0; i < t.length(); i++) {
int c = (int) t.charAt(i);
letters[c]--;
if (letters[c] < 0) { // this is the line in question
return false;
}
}
return true;
}
The comparison for != 0 only makes sense after all the differences are computed. The way the code is structured allows an early detection.
The very first test is for s.length() != t.length(). Once the code passed it, we know that there are equal number of characters. It means that - if the strings are not permutations - there is a character which appears more in t than in s. As soon as such character is found, we conclude that t is not a permutation.

Can anyone explain why this code concatenates rather than adds the numerical values?

So, to start off, I know this code is messy, please bear with me, but can anyone explain why this keeps concatenating the entered information rather than adding the numerical values after being passed through parseInt()?
var sol = 0;
var n = 0;
while(n !== null)
{
parseInt(n = prompt("Please enter a number to be added onto stack"));
if(n != null || n != NaN)
{
sol = parseInt(sol);
sol += n;
}
}
console.log(sol);
prompt() returns a string.
parseInt() accepts a string and returns a number.
You aren't doing anything with the return value of the first parseInt. This means n is a string. So when you do sol += n you are adding a string and number together, and javascript assumes that you meant to concatenate strings together, since math with a string and number doesn't make any sense.
You probably meant to do:
n = parseInt(prompt("Please enter a number to be added onto stack"));

Sum Strings as Numbers

I am trying to solve a kata that seems to be simple on codewars but i seem to not be getting it right.
The instruction for this is as simple as below
Given the string representations of two integers, return the string representation of the sum of those integers.
For example:
sumStrings('1','2') // => '3'
A string representation of an integer will contain no characters besides the ten numerals "0" to "9".
And this is what i have tried
function sumStrings(a,b) {
return ((+a) + (+b)).toString();
}
But the results solves all except two and these are the errors i get
sumStrings('712569312664357328695151392', '8100824045303269669937') - Expected: '712577413488402631964821329', instead got: '7.125774134884027e+26'
sumStrings('50095301248058391139327916261', '81055900096023504197206408605') - Expected: '131151201344081895336534324866', instead got: '1.3115120134408189e+29'
I don't seem to understand where the issues is from. Any help would help thanks.
The value you entered is bigger than the int type max value. You can try changing your code to:
function sumStrings(a,b) {
return ((BigInt(a)) + BigInt(b)).toString();
}
This way it should return the right value
You could pop the digits and collect with a carry over for the next digit.
function add(a, b) {
var aa = Array.from(a, Number),
bb = Array.from(b, Number),
result = [],
carry = 0,
i = Math.max(a.length, b.length);
while (i--) {
carry += (aa.pop() || 0) + (bb.pop() || 0);
result.unshift(carry % 10);
carry = Math.floor(carry / 10);
}
while (carry) {
result.unshift(carry % 10);
carry = Math.floor(carry / 10);
}
return result.join('');
}
console.log(add('712569312664357328695151392', '8100824045303269669937'));
console.log(add('50095301248058391139327916261', '81055900096023504197206408605'));
The problem is that regular javascript integers are not having enough space to store that much big number, So it uses the exponential notation to not lose its precision
what you can do is split each number into parts and add them separately,
one such example is here SO answer
My solution is:
function sumStrings(a,b) {
return BigInt(a) + BigInt(b) + ''
}
Converting from a string to a number or vice versa is not perfect in any language, they will be off by some digits. This doesn't seem to affect small numbers, but it affects big numbers a lot.
The function could go like this.
function sumStrings(a, b) {
return (BigInt(a) + BigInt(b)).toString() // or parseInt for both
}
However, it's still not perfect since if we try to do:
console.log((4213213124214211215421314213.0 + 124214321214213434213124211.0) === sumStrings('4213213124214211215421314213', '124214321214213434213124211'))
The output would be false.

counting a word and returning a whether it is symmetric or not in Javascript

My whole goal was to write a loop that would take a string, count the letters and return two responses: one = "this word is symmetric" or two = "this word is not symmetric". However the code I wrote doesn't console anything out. Here's the code:
var arya = function(arraycount){
for (arraycount.length >= 1; arraycount.length <= 100; arraycount++) {
while (arraycount.length%2 === 0) {
console.log("This is a symmetric word and its length is " + " " arraycount.length " units.");
arraycount.length%2 != 0
console.log("Not a symmetric word");
}
}
}
arya("Michael");
There are many ways to accomplish your goal, but here are a few. The first is a somewhat naïve approach using a for loop, and the second uses recursion. The third asks whether the string equals the reverse of the string.
iterative (for loop) function
var isPalindromeIteratively = function(string) {
if (string.length <= 1) {
return true;
}
for (var i = 0; i <= Math.floor(string.length / 2); i++) {
if (string[i] !== string[string.length - 1 - i]) {
return false;
}
}
return true;
};
This function begins by asking whether your input string is a single character or empty string, in which case the string would be a trivial palindrome. Then, the for loop is set up: starting from 0 (the first character of the string) and going to the middle character, the loop asks whether a given character is identical to its partner on the other end of the string. If the parter character is not identical, the function returns false. If the for loop finishes, that means every character has an identical partner, so the function returns true.
recursive function
var isPalindromeRecursively = function(string) {
if (string.length <= 1) {
console.log('<= 1');
return true;
}
var firstChar = string[0];
var lastChar = string[string.length - 1];
var substring = string.substring(1, string.length - 1);
console.log('first character: ' + firstChar);
console.log('last character: ' + lastChar);
console.log('substring: ' + substring);
return (firstChar === lastChar) ? isPalindromeRecursively(substring) : false;
};
This function begins the same way as the first, by getting the trivial case out of the way. Then, it tests whether the first character of the string is equal to the last character. Using the ternary operator, the function, returns false if that test fails. If the test is true, the function calls itself again on a substring, and everything starts all over again. This substring is the original string without the first and last characters.
'reflecting' the string
var reflectivePalindrome = function(string) {
return string === string.split('').reverse().join('');
};
This one just reverses the string and sees if it equals the input string. It relies on the reverse() method of Array, and although it's the most expressive and compact way of doing it, it's probably not the most efficient.
usage
These will return true or false, telling you whether string is a palindrome. I assumed that is what you mean when you say "symmetric." I included some debugging statements so you can trace this recursive function as it works.
The Mozilla Developer Network offers a comprehensive guide of the JavaScript language. Also, here are links to the way for loops and while loops work in JS.

Is there a splice method for strings?

The Javascript splice only works with arrays. Is there similar method for strings? Or should I create my own custom function?
The substr(), and substring() methods will only return the extracted string and not modify the original string. What I want to do is remove some part from my string and apply the change to the original string. Moreover, the method replace() will not work in my case because I want to remove parts starting from an index and ending at some other index, exactly like what I can do with the splice() method. I tried converting my string to an array, but this is not a neat method.
It is faster to slice the string twice, like this:
function spliceSlice(str, index, count, add) {
// We cannot pass negative indexes directly to the 2nd slicing operation.
if (index < 0) {
index = str.length + index;
if (index < 0) {
index = 0;
}
}
return str.slice(0, index) + (add || "") + str.slice(index + count);
}
than using a split followed by a join (Kumar Harsh's method), like this:
function spliceSplit(str, index, count, add) {
var ar = str.split('');
ar.splice(index, count, add);
return ar.join('');
}
Here's a jsperf that compares the two and a couple other methods. (jsperf has been down for a few months now. Please suggest alternatives in comments.)
Although the code above implements functions that reproduce the general functionality of splice, optimizing the code for the case presented by the asker (that is, adding nothing to the modified string) does not change the relative performance of the various methods.
Edit
This is of course not the best way to "splice" a string, I had given this as an example of how the implementation would be, which is flawed and very evident from a split(), splice() and join(). For a far better implementation, see Louis's method.
No, there is no such thing as a String.splice, but you can try this:
newStr = str.split(''); // or newStr = [...str];
newStr.splice(2,5);
newStr = newStr.join('');
I realise there is no splice function as in Arrays, so you have to convert the string into an array. Hard luck...
Here's a nice little Curry which lends better readability (IMHO):
The second function's signature is identical to the Array.prototype.splice method.
function mutate(s) {
return function splice() {
var a = s.split('');
Array.prototype.splice.apply(a, arguments);
return a.join('');
};
}
mutate('101')(1, 1, '1');
I know there's already an accepted answer, but hope this is useful.
There seem to be a lot of confusion which was addressed only in comments by elclanrs and raina77ow, so let me post a clarifying answer.
Clarification
From "string.splice" one may expect that it, like the one for arrays:
accepts up to 3 arguments: start position, length and (optionally) insertion (string)
returns the cut out part
modifies the original string
The problem is, the 3d requirement can not be fulfilled because strings are immutable (related: 1, 2), I've found the most dedicated comment here:
In JavaScript strings are primitive value types and not objects (spec). In fact, as of ES5, they're one of the only 5 value types alongside null, undefined, number and boolean. Strings are assigned by value and not by reference and are passed as such. Thus, strings are not just immutable, they are a value. Changing the string "hello" to be "world" is like deciding that from now on the number 3 is the number 4... it makes no sense.
So, with that in account, one may expect the "string.splice" thing to only:
accepts up to 2 arguments: start position, length (insertion makes no sense since the string is not changed)
returns the cut out part
which is what substr does; or, alternatively,
accepts up to 3 arguments: start position, length and (optionally) insertion (string)
returns the modified string (without the cut part and with insertion)
which is the subject of the next section.
Solutions
If you care about optimizing, you should probably use the Mike's implementation:
String.prototype.splice = function(index, count, add) {
if (index < 0) {
index += this.length;
if (index < 0)
index = 0;
}
return this.slice(0, index) + (add || "") + this.slice(index + count);
}
Treating the out-of-boundaries index may vary, though. Depending on your needs, you may want:
if (index < 0) {
index += this.length;
if (index < 0)
index = 0;
}
if (index >= this.length) {
index -= this.length;
if (index >= this.length)
index = this.length - 1;
}
or even
index = index % this.length;
if (index < 0)
index = this.length + index;
If you don't care about performance, you may want to adapt Kumar's suggestion which is more straight-forward:
String.prototype.splice = function(index, count, add) {
var chars = this.split('');
chars.splice(index, count, add);
return chars.join('');
}
Performance
The difference in performances increases drastically with the length of the string. jsperf shows, that for strings with the length of 10 the latter solution (splitting & joining) is twice slower than the former solution (using slice), for 100-letter strings it's x5 and for 1000-letter strings it's x50, in Ops/sec it's:
10 letters 100 letters 1000 letters
slice implementation 1.25 M 2.00 M 1.91 M
split implementation 0.63 M 0.22 M 0.04 M
note that I've changed the 1st and 2d arguments when moving from 10 letters to 100 letters (still I'm surprised that the test for 100 letters runs faster than that for 10 letters).
I would like to offer a simpler alternative to both the Kumar/Cody and the Louis methods. On all the tests I ran, it performs as fast as the Louis method (see fiddle tests for benchmarks).
String.prototype.splice = function(startIndex,length,insertString){
return this.substring(0,startIndex) + insertString + this.substring(startIndex + length);
};
You can use it like this:
var creditCardNumber = "5500000000000004";
var cardSuffix = creditCardNumber.splice(0,12,'****');
console.log(cardSuffix); // output: ****0004
See Test Results:
https://jsfiddle.net/0quz9q9m/5/
Simply use substr for string
ex.
var str = "Hello world!";
var res = str.substr(1, str.length);
Result = ello world!
The method Louis's answer, as a String prototype function:
String.prototype.splice = function(index, count, add) {
if (index < 0) {
index = this.length + index;
if (index < 0) {
index = 0;
}
}
return this.slice(0, index) + (add || "") + this.slice(index + count);
}
Example:
> "Held!".splice(3,0,"lo Worl")
< "Hello World!"
So, whatever adding splice method to a String prototype cant work transparent to spec...
Let's do some one extend it:
String.prototype.splice = function(...a){
for(var r = '', p = 0, i = 1; i < a.length; i+=3)
r+= this.slice(p, p=a[i-1]) + (a[i+1]||'') + this.slice(p+a[i], p=a[i+2]||this.length);
return r;
}
Every 3 args group "inserting" in splice style.
Special if there is more then one 3 args group, the end off each cut will be the start of next.
'0123456789'.splice(4,1,'fourth',8,1,'eighth'); //return '0123fourth567eighth9'
You can drop or zeroing the last arg in each group (that treated as "nothing to insert")
'0123456789'.splice(-4,2); //return '0123459'
You can drop all except 1st arg in last group (that treated as "cut all after 1st arg position")
'0123456789'.splice(0,2,null,3,1,null,5,2,'/',8); //return '24/7'
if You pass multiple, you MUST check the sort of the positions left-to-right order by youreself!
And if you dont want you MUST DO NOT use it like this:
'0123456789'.splice(4,-3,'what?'); //return "0123what?123456789"
Louis's spliceSlice method fails when add value is 0 or other falsy values, here is a fix:
function spliceSlice(str, index, count, add) {
if (index < 0) {
index = str.length + index;
if (index < 0) {
index = 0;
}
}
const hasAdd = typeof add !== 'undefined';
return str.slice(0, index) + (hasAdd ? add : '') + str.slice(index + count);
}
I solved my problem using this code, is a somewhat replacement for the missing splice.
let str = "I need to remove a character from this";
let pos = str.indexOf("character")
if(pos>-1){
let result = str.slice(0, pos-2) + str.slice(pos, str.length);
console.log(result) //I need to remove character from this
}
I needed to remove a character before/after a certain word, after you get the position the string is split in two and then recomposed by flexibly removing characters using an offset along pos

Categories

Resources