I don't know why I have a comma when I use join method. Can anyone explain?
function maskify(cc) {
var a = cc.slice(cc.length - 4, cc.length);
var b = cc.slice(0, cc.length - 4);
b = b.split("");
for (var i = 0; i < b.length; i++) {
b[i] = "#";
}
b.join("#");
console.log(b + a);
}
maskify("sadasdasdasdasdasd");
// result : #,#,#,#,#,dasd
Join() is the method of array which allows to join its element as string and returns. Join() takes one argument which is separator, the default value is ",". You need to specify empty string if you want to join without any separator. For reference refer MDN.
For your code, you are joining but not storing, and again converting it to string by using + operator with variable a
function maskify(cc) {
var a = cc.slice(cc.length - 4, cc.length);
var b = cc.slice(0, cc.length - 4);
b = b.split("");
for (var i = 0; i < b.length; i++) {
b[i] = "#";
}
var output=b.join("#");
console.log(output + a);
}
maskify("sadasdasdasdasdasd");
// result : #,#,#,#,#,dasd
When you use split on b, b is an array of individual characters. When logging b + a, since b is an array and a a string, + will act as string concatenation operator. b is converted to string using toString() implicitly. toString on array returns string of array elements joined by ,. So, you're getting comma in the final output.
Simple solution to solve this problem is to explicitly join the array elements before concatenating.
function maskify(cc) {
var a = cc.slice(cc.length - 4, cc.length);
var b = cc.slice(0, cc.length - 4);
b = b.split("");
for (var i = 0; i < b.length; i++) {
b[i] = "#";
}
b.join("#");
console.log(b.join('') + a);
}
maskify("sadasdasdasdasdasd");
Another way to achieve same results is using repeat
var str = 'sadasdasdasdasdasd';
var maskedStr = '#'.repeat(str.length -4) + str.slice(-4);
console.log(maskedStr);
Note that this is supported in latest browsers/environments only. Check the browser compatibility, if not supported use polyfill.
It's because when concatinating an array and a string, the array is implicitly converted into a string.
var array = [...];
array + "";
is the same as:
array.toString() + "";
and [4, 5].toString() is "4,5" (add a , by default).
Why?
Because, when this line is reached:
console.log(b + a);
a will be a string because it was cut from the string cc. And b is an array because it is the result of the split, and b.join don't change b to a string, it just return a string that you don't use and leaves b intact (so b remains an array).
Fix:
Use the result of b.join not b:
console.log(b.join("#") + a);
or:
b = b.join("#");
console.log(b + a);
i add
var c = b.concat(a);
c.join("");
It's working . Thanks u so much :D
Related
A simple way of reversing a string is as below:
const test = 'hello';
let i = 0;
let j = test.length - 1;
while (i < j) {
let temp = test[i];
test[j] = test[i];
test[i] = temp;
i++;
j--;
}
console.log(test);
If we try to access string using an index it works fine. For example console.log(test[2]) returns 'l'
But reversing a string using the method above returns unchanged string 'hello'. We need to use an array, reverse it and then join it to return the reversed string. But in that case we will be using an extra space. Can we do it without using an extra space?
Strings are immutable in JavaScript. Therefore, they cannot be changed in-place. Any new string requires a new memory allocation, even when doing something as simple as
const str1 = "hello";
const str2 = str[0];
Leaves two strings in memory: "hello" and "h".
Since any attempt to produce a string will create at least one new string, it is therefore impossible to reverse a string without allocating space for a new string where the characters are reversed.
The minimum space complexity for this task is thusO(n) - scales linearly with the string length. Creating an array which can be rearranged in-place and then combined back to the reversed string fulfils this.
Here is a recursive way of doing it:
const rev = s => s.length>1 ? s.at(-1)+rev(s.slice(0,-1)) : s;
console.log(rev("This is a test string."))
The final line of your question means that the answer is "no". We cannot do this without using extra space [in userland JS].
We could, however, do this if we relied on a function written in a systems programming language. And this is the C code used by V8 for Array#join. In such a language the binary representation of the reversed string could be constructed step by step and simply cast to be a UTF-16 string in the final step. I presume this approximates what Array#join does under the hood.
If your requirement is simply to avoid using an array, the following simply successively pulls the code units from the end of the input string and builds a new string from them.
This will fail horribly with surrogate pairs (eg emoji) and grapheme clusters.
const reverse = (s) => {
let result = ''
for(let x = s.length-1; x >= 0; x--) {
result += s[x]
}
return result
}
console.log(reverse('hello'))
What about a hacky for loop?
const rev = (str) => {
for(var i = str.length - 1; i >= 0; i--) {
str += str[i];
}
return str.slice(str.length / 2, str.length);
}
console.log(rev("t"));
console.log(rev("te"));
console.log(rev("tes"));
console.log(rev("test"));
OP
"Can we do it without using an extra space."
nope.
Anyhow ... the OP's while based approached which this time does not try to change characters in place but programmatically a) removes character by character from the input value while b) concatenating the reversed result string ...
function reverseStringWithoutHelpOfArray(value) {
value = String(value); // let i = 0;
let result = ''; // let j = test.length - 1;
// while (i < j) {
while (value) { // let temp = test[i];
result = result + value.slice(-1); // test[j] = test[i];
value = value.substring(0, value.length - 1); // test[i] = temp;
} // i++; j--;
return result; // }
}
console.log(
reverseStringWithoutHelpOfArray('hallo')
);
I am working on a Url decoding and encoding system. But for some odd reason, it will only decode/encode certain string. Also, it seems to decode/encode a string when it has a certain piece in it. It is quite hard to explain but it is quite confusion as to what this might not work. I tried figuring out the problem of it but it just makes the whole issue seem more illogical than logical.
I hope someone can help me with this. With explanation to it. I would like it if the code is in the same style as it is as well.
I also know that there are probably some packages online to easily do that but I would rather just make my own. It's a way I can practice JS more.
// I know I don't have all the characters markek. I am doing that later
var Url = {
filterEncode : ["%2B","%3A","%3D","%3F","%2F","%26","%252F","%253A","%253D","%253F","%252B"],
filterDecode : ["+",":","=","?","/","&","%2F","%3A","%3D","%3F","%2B"],
decode : function(decodeText){
let returnString, a, b;
let filterEncode = Url.filterEncode;
let filterDecode = Url.filterDecode;
for (a = 0; a < filterEncode.length; a++){
let regexEn = new RegExp(filterEncode[a],"g");
let regexDe = new RegExp("/" + filterDecode[a],"g");
let regex = new RegExp(regexEn,"g");
let array = (decodeText.match(regex) || []).length
for (b = 0; b < array; b++){
returnString = decodeText.replace(filterEncode[a],filterDecode[a]);
decodeText = returnString;
}
}
return returnString;
},
encode : function(encodeText){
let returnString, a, b;
let filterEncode = Url.filterEncode;
let filterDecode = Url.filterDecode;
for (a = 0; a < filterEncode.length; a++){
let regexEn = new RegExp("[" + filterEncode[2] + "]","g");
let regexDe = new RegExp("[" + filterDecode[2] + "]","g");
let regex = new RegExp(regexEn,"g");
let array = (encodeText.match(regex) || []).length;
for (b = 0; b < array; b++){
returnString = encodeText.replace(filterDecode[a],filterEncode[a]);
encodeText = returnString;
}
}
return returnString;
}
}
// Saying it is undefined
console.log(Url.encode("="));
// Encodes it just find
console.log(Url.encode("%3F"));
// Encodes both of them but for some odd reason encodes the
// equal sign twice.
console.log(Url.encode("%3F ="));
I do hope everything seems clear as to what my problem is about. I usually would just try searching on here for an answer, but this problem is so confusion, I don't know what I exactly should search for.
Thanks!
Some of your strings in filterDecode have special meaning as regular expressions. When converting the string to a regular expression, you need to wrap each character in [] so it will be matched literally.
You don't need to concatenate / when creating regexDe.
There's no need for the for(b...) loops. Use the regular expression in the replace() call and it will perform all the replacements at once, since it has the g flag.
Put the encode strings that contain % at the beginning of the array. Otherwise, when you encode something like = as %3D, a later iteration of the outer loop will re-encode that as %253D. You only want to encode this if it was in the original string, not an intermediate step.
var Url = {
filterDecode: ["%252F", "%253A", "%253D", "%253F", "%252B", "%2B", "%3A", "%3D", "%3F", "%2F", "%26"],
filterEncode: ["%2F", "%3A", "%3D", "%3F", "%2B", "+", ":", "=", "?", "/", "&"],
strToRe: function(str) {
let reStr = str.split("").map(c => '[' + c + ']').join('');
return new RegExp(reStr, "g");
},
decode: function(decodeText) {
let a;
let filterEncode = Url.filterEncode;
let filterDecode = Url.filterDecode;
for (a = 0; a < filterDecode.length; a++) {
decodeText = decodeText.replace(Url.strToRe(filterDecode[a]), filterEncode[a]);
}
return decodeText;
},
encode: function(encodeText) {
let a, b;
let filterEncode = Url.filterEncode;
let filterDecode = Url.filterDecode;
for (a = 0; a < filterEncode.length; a++) {
encodeText = encodeText.replace(Url.strToRe(filterEncode[a]), filterDecode[a]);
}
return encodeText;
}
}
console.log(Url.encode("="));
console.log(Url.decode("%3D"));
console.log(Url.encode("%3F"));
console.log(Url.decode("%253F"));
console.log(Url.encode("%3F ="));
console.log(Url.decode("%253F %3D"));
This question has been asked before however I wanted to know what is wrong with my solution (I can Google a solution but more interested in learning what I am doing wrong). I want to reverse a string without using a major builtin function that does it. Below is my code but it returns the same string,
s="hello";
var opp=s;
for (var i=0; i< s.length; i++)
{
opp[i] = s[s.length-i];
}
alert (opp);
Your code returns the same string because in JavaScript strings are frozen. Any attempt to modify string will be ignored. Instead you need to build new string according to your rules.
You can update your code by assigning opp to empty string: var opp = '' and then pushing chars to it in reverse order: opp += s[s.length-i].
Also I found a bug in your code. What will return the first iteration? It will try to access char at missing position: s.length - i = s.length - 0 = s.length. Because in JavaScript strings and arrays are zero indexed the max char index in your string will be s.length - 1. You are trying to access s.length.
Strings are immutable: you cannot assign to an index. opp[i] is read-only.
An alternative is to use an array:
s = "hello";
var opp = [];
var len = s.length - 1;
for (var i = 0; i <= len; i++)
opp[i] = s[len - i];
console.log(opp.join(""));
with reduce
'some word'
.split('')
.reduce(({str, tail}, char, i, word) => {
return {tail: tail - 1, str: str + word[word.length + tail]}
}, {str: '', tail: -1})
.str
I am trying to chop the last ; off an array that has been converted to a string.
Substring and slice don't appear to be doing this?
The two pieces of data i get back are below, but i can remove that last ;.
CN=user1,OU=Security,OU=Groups,OU=Corp,DC=test,DC=company,DC=com;
CN=user2,OU=Security,OU=Groups,OU=Corp,DC=test,DC=company,DC=com;
var removeUsersList = current.variables.RemoveUserOrGroup;
if(removeUsersList)
{
var b = JSON.parse(removeUsersList);
var removeUserdns = "";
for (var key1 in b)
{
if(b.hasOwnProperty(key1))
{
removeUserdns += b[key1].DistinguishedName + ";";
}
}
removeUserdns.toString();
removeUserdns.substring(0, removeUserdns.length - 1);
// removeUserdns.slice(0, -1);
}
You need to do this:
removeUserdns = removeUserdns.substring(0, removeUserdns.length - 1);
because string behave as immutable, substring method returns a new string which you need to assign to removeUserdns.
HI ,
In Java Script ,
var a ="apple-orange-mango"
var b ="grapes-cheery-apple"
var c = a + b // Merging with 2 variable
var c should have value is "apple-orange-mango-grapes-cheery" .Duplicated should be removed.
Thanks ,
Chells
After your string is combined, you will want to split it using the delimiters (you can add these back in later).
example:
var a ="apple-orange-mango"
var b ="grapes-cheery-apple"
var c = a + "-" + b
var Splitted = c.split("-");
the Splitted variable now contains an array such as [apples,orange,mango,grapes,cherry,apple]
you can then use one of many duplicate removing algorithms to remove the duplicates. Then you can simply do this to add your delimiters back in:
result = Splitted.join("-");
Here's a brute force algorithm:
var a;
var b; // inputs
var words = split(a+b);
var map = {};
var output;
for( index in words ) {
if( map[ words[index] ]!=undefined ) continue;
map[ words[index] ] = true;
output += (words[index] + '-');
}
output[output.length-1]=' '; // remove the last '-'
The map acts as a hashtable.
Thats it!
I don't know if it is an homework.
By the way you can split strings like a and b with the split method of string object.
in your case:
firstArray=a.split("-");
secondArray=b.split("-");
the removal of duplicates is up to you...
In your simple example, just use var c = a + "-" + b;
If you want duplicates removed, split a and b into arrays, and combine them, like so:
var avalues = a.split("-");
var bvalues = b.split("-");
var combined = avalues.concat( bvalues );
// now loop over combined and remove duplicates