javascript toLowerCase() function returns different string - javascript

console.log("HİNDİ".toLocaleLowerCase() == "hindi");
console.log("HİNDİ" == "hindi");
console.log("HİNDİ".toLowerCase());
console.log("HİNDİ".toLocaleLowerCase())
console.log("HİNDİ".toLowerCase())
I am building a search functionality but i come across a thing:
"HİNDİ".toLocaleLowerCase() // "hindi"
"hindi" == "HİNDİ".toLocaleLowerCase() //false
What the heck is going on here?
Solution:
#pmrotule's answer seems to work:
function to_lower(s)
{
var n = "";
for (var i = 0; i < s.length; i++) // do it for one character at a time
{
var c = s[i].toLowerCase();
// call replace() only if the character has a length > 1
// after toLowerCase()
n += c.length > 1 ? c[0].replace(/[^ -~]/g,'') : c;
}
return n;
}
Thanks,

It is a problem of string format. toLocaleLowerCase is meant for human-readable display only. However, there is still a trick you can do:
if ("hindi" == "HİNDİ".toLowerCase().replace(/[^ -~]/g,''))
{
alert("It works!");
}
EDIT
If you want to make it works with all special characters:
function to_lower(s)
{
var n = "";
for (var i = 0; i < s.length; i++) // do it for one character at a time
{
var c = s[i].toLowerCase();
// call replace() only if the character has a length > 1
// after toLowerCase()
n += c.length > 1 ? c.replace(/[^ -~]/g,'') : c;
}
return n;
}
console.log("gök" == to_lower("GÖK"));
console.log("hindi" == to_lower("HİNDİ"));
function to_low(s) // shorter version
{
var n = "";
for (var i = 0; i < s.length; i++)
{ n += s[i].toLowerCase()[0]; }
return n;
}
console.log("hindi" == to_low("HİNDİ"));

The problem is that your character İ is composed by 2 characters.
You have the I and then the 'dot' at the top (UTF-8 decimal code: 775).
Try this:
"HİNDİ".toLocaleLowerCase().split('').map((_,v)=>console.log(_.charCodeAt(0)))
Compare it with this:
"hindi".toLocaleLowerCase().split('').map((_,v)=>console.log(_.charCodeAt(0)))

Related

Check if a string is palindrome using only pure javascript

I have this function
function palindrome(str){
var myStr = "";
for (var index = str.length -1 ; index >=0; index--) {
myStr += str[index]
}
var res = myStr == str ? true : false;
return res;
}
It works with a single word , but if i checked such as "I did, did I?" , it don't works. How i can check is without using replace , join , reverse , etc... Only pure js . Thanks very much .
This is how i do it, run the loop both incremental and decremental fashion at the same time
function palindrome() {
var str = "dd dd";
var Ispalindrome = true;
for (var i = 0, j = str.length - 1; i < str.length && j >= 0; i++, j--) {
if (str[i] !== str[j]) {
Ispalindrome = false;
}
}
alert(Ispalindrome);
return Ispalindrome;
}
//Invoked
palindrome()

Comparison operator not working(Java Script)

I am trying to replace all the letters of a string by the next letter in the alphabet.
For example: a --> b or i --> j.
My program is ignoring the if statement that checks a letter against the alphabet array. When I try running the code it replaces all letters by "A", the last element in the alphabet array.
Although inefficent, I cannot find any errors with this algorithm. So why is the program ignoring the if statement?
function LetterChanges(str){
var alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","a"];
str = str.toLowerCase();
var ans = str.split("");
for(i = 0; i < ans.length; i ++)//Running through for each letter of the input string
{
for(a = 0; a < 26; a++)//Checking each letter against the alphabet array
{
if(alphabet[a] == ans[i])
{
ans[i] = alphabet[a+1];
}
}
}
return ans;
}
LetterChanges("Argument goes here");
The reason why it is not working, is because the ans array is modified, whilst you are still checking it.
In this loop:
for(a = 0; a < 26; a++)//Checking each letter against the alphabet array
{
if(alphabet[a] == ans[i])
{
ans[i] = alphabet[a+1];
}
}
If the if statement is found to be true, ans[i] will be updated, but then on the next loop of the iteration, it will likely be true again, as you are checking against the updated ans[i] variable.
As #xianshenglu suggested, you can fix this issue by adding a break to escape from the inner loop once a correct match is found.
for(a = 0; a < 26; a++) {
if(alphabet[a] == ans[i]) {
ans[i] = alphabet[a+1]
// escape from the inner loop once a match has been found
break
}
}
For an alternative way to do this, you could do the following:
var result = str.toLowerCase().split('').map(ch => {
var pos = alphabet.indexOf(ch)
return pos >= 0 ? alphabet[pos + 1] : ch
}).join('')
And if you want to get rid of the alphabet array, you can use char codes. For example:
var result = str.toLowerCase().split('').map(ch => {
var code = ch.charCodeAt(0)
if(code < 96 || code > 122){ return ch }
return String.fromCharCode((code - 96) % 26 + 97)
}).join('')
you lost break when if executed
function LetterChanges(str){
var alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","a"];
str = str.toLowerCase();
var ans = str.split("");
for(i = 0; i < ans.length; i ++)//Running through for each letter of the input string
{
for(a = 0; a < 26; a++)//Checking each letter against the alphabet array
{
if(alphabet[a] == ans[i])
{
ans[i] = alphabet[a+1];
break;
}
}
}
return ans;
}
console.log(LetterChanges("Argument goes here"));

How do you iterate over an array every x spots and replace with letter?

/Write a function called weave that accepts an input string and number. The function should return the string with every xth character replaced with an 'x'./
function weave(word,numSkip) {
let myString = word.split("");
numSkip -= 1;
for(let i = 0; i < myString.length; i++)
{
numSkip += numSkip;
myString[numSkip] = "x";
}
let newString = myString.join();
console.log(newString);
}
weave("weave",2);
I keep getting an infinite loop. I believe the answer I am looking for is "wxaxe".
Here's another solution, incrementing the for loop by the numToSkip parameter.
function weave(word, numToSkip) {
let letters = word.split("");
for (let i=numToSkip - 1; i < letters.length; i = i + numToSkip) {
letters[i] = "x"
}
return letters.join("");
}
Well you need to test each loop to check if it's a skip or not. Something as simple as the following will do:
function weave(word,numSkip) {
var arr = word.split("");
for(var i = 0; i < arr.length; i++)
{
if((i+1) % numSkip == 0) {
arr[i] = "x";
}
}
return arr.join("");
}
Here is a working example
Alternatively, you could use the map function:
function weave(word, numSkip) {
var arr = word.split("");
arr = arr.map(function(letter, index) {
return (index + 1) % numSkip ? letter : 'x';
});
return arr.join("");
}
Here is a working example
Here is a more re-usable function that allows specifying the character used for substitution:
function weave(input, skip, substitute) {
return input.split("").map(function(letter, index) {
return (index + 1) % skip ? letter : substitute;
}).join("");
}
Called like:
var result = weave('weave', 2, 'x');
Here is a working example
You dont need an array, string concatenation will do it, as well as the modulo operator:
function weave(str,x){
var result = "";
for(var i = 0; i < str.length; i++){
result += (i && (i+1)%x === 0)?"x":str[i];
}
return result;
}
With arrays:
const weave = (str,x) => str.split("").map((c,i)=>(i&&!((i+1)%x))?"x":c).join("");
You're getting your word greater in your loop every time, so your loop is infinite.
Try something like this :
for(let k = 1; k <= myString.length; k++)
{
if(k % numSkip == 0){
myString[k-1]='x';
}
}
Looking at what you have, I believe the reason you are getting an error is because the way you update numSkip, it eventually becomes larger than
myString.length. In my code snippet, I make i increment by numSkip which prevents the loop from ever executing when i is greater than myString.length. Please feel free to ask questions, and I will do my best to clarify!
JSFiddle of my solution (view the developer console to see the output.
function weave(word,numSkip) {
let myString = word.split("");
for(let i = numSkip - 1; i < myString.length; i += numSkip)
{
myString[i] = "x";
}
let newString = myString.join();
console.log(newString);
}
weave("weave",2);
Strings are immutable, you need a new string for the result and concat the actual character or the replacement.
function weave(word, numSkip) {
var i, result = '';
for (i = 0; i < word.length; i++) {
result += (i + 1) % numSkip ? word[i] : 'x';
}
return result;
}
console.log(weave("weave", 2));
console.log(weave("abcd efgh ijkl m", 5));
You can do this with fewer lines of code:
function weave(word, numSkip) {
word = word.split("");
for (i = 0; i < word.length; i++) {
word[i] = ((i + 1) % numSkip == 0) ? "x" : word[i];
}
return word.join("");
}
var result = weave("weave", 2);
console.log(result);

checking if a substring of length 5 is in another string (refactored)

I'm trying to check if string b contains any 5-character substring a.
This works, but is a little messy:
var a = "1eabcde";
var b = "12abcde12fg";
for(var i=0; i<a.length; i++){
for(var j=i;j<a.length-i;j++){
if(a.charAt(j) == b.charAt(i) && a.charAt(j+1) == b.charAt(i+1) && a.charAt(j+2) == b.charAt(i+2) && a.charAt(j+3) == b.charAt(i+3) && a.charAt(j+4) == b.charAt(i+4)){
alert("ya");
}
}
}
Are there any other cleaner options?
You can use substring and indexOf:
var a = "1eabcde";
var b = "12abcde12fg";
for (var i = 0; i <= a.length - 5; i++) {
if (b.indexOf(a.substring(i, i + 5)) >= 0) {
alert("ya");
}
}
(You could use a.substr(i, 5) instead of a.substring(i, i + 5). Those two calls behave identically.)
Note that if you loop from 0 to a.length (as in your original code), then all suffixes of a of length 5 or less will be searched for in b.
In one respect, this code does not behave the same as your original: it will alert only once for each matching substring of a, regardless of how many times that particular substring may occur in b. Thus, if a = 'abcde' and b = '01abcde23abcde45, your original code would pop up two alerts (one for each occurrence of 'abcde'), whereas the above will only alert once. If you want the original behavior, change the if to a while like this:
for (var i = 0; i <= a.length - 5; i++) {
var j = -1;
while ((j = b.substring(j+1).indexOf(a.substr(i, 5))) >= 0) {
alert("ya");
}
}
This is the cleanest approach :
var a = "1eabcde";
var b = "12abcde12fg";
for (var i = 0; i <= a.length - 5; i++) {
if(b.indexOf(a.substr(i, 5)) > -1) {
alert("ya");
}
}

Insert dashes into a number

Any ideas on the following? I want to input a number into a function and insert dashes "-" between the odd digits. So 4567897 would become "456789-7". What I have so far is to convert the number into a string and then an array, then look for two odd numbers in a row and use the .splice() method to add the dashes where appropriate. It does not work and I figure I may not be on the right track anyway, and that there has to be a simpler solution.
function DashInsert(num) {
var numArr = num.toString().split('');
for (var i = 0; i < numArr.length; i++){
if (numArr[i]%2 != 0){
if (numArr[i+1]%2 != 0) {
numArr.splice(i, 0, "-");
}
}
}
return numArr;
}
The problem is you're changing the thing you're iterating over. If instead you maintain a separate output and input...
function insertDashes(num) {
var inStr = String(num);
var outStr = inStr[0], ii;
for (ii = 1; ii < inStr.length; ii++) {
if (inStr[ii-1] % 2 !== 0 && inStr[ii] % 2 !== 0) {
outStr += '-';
}
outStr += inStr[ii];
}
return outStr;
}
You can try using regular expressions
'4567897'.replace(/([13579])(?=[13579])/g, '$1-')
Regex Explained
So, we find an odd number (([13579]) is a capturing group meaning we can use it as a reference in the replacement $1) ensure that it is followed by another odd number in the non-capturing positive lookahead ((?=[13579])) and replace the matched odd number adding the - prefix
Here is the function to do it:
function dashes(number){
var numString = '';
var numArr = number.toString().split('');
console.log(numArr);
for(i = 0; i < numArr.length; i++){
if(numArr[i] % 2 === 1 && numArr[i+1] % 2 === 1){
numString += numArr[i] + '-';
}else{
numString += numArr[i];
}
}
console.log(numString);
}
dashes(456379);
Tested and everything.
Edit: OrangeDog's answer was posted earlier (by nearly a full half hour), I just wanted to make an answer which uses your code since you're almost there.
Using another array instead of splicing into one you were looping through (this happens to return a string using join):
var num = 4567897;
function DashInsert(num) {
var numArr = num.toString().split('');
var len = numArr.length;
var final = [];
for (var i = 0; i < len; i++){
final.push(numArr[i]);
if (numArr[i]%2 != 0){
if (i+1 < len && numArr[i+1]%2 != 0) {
final.push("-")
}
}
}
return final.join("");
}
alert(DashInsert(num));
function dashInsert(str) {
var arrayNumbers = str.split("");
var newString = "";
for (var i = 0; i < arrayNumbers.length; i++){
if(arrayNumbers[i] % 2 === 1 && arrayNumbers[i + 1] % 2 === 1){
newString = newString + arrayNumbers[i] + "-";
} else {
newString = newString + arrayNumbers[i];
}
}
return newString;
}
var result = dashInsert("3453246");
console.log(result);

Categories

Resources