Why my reverse array function's output is as same as input? - javascript

I want to write a reverse array function and I met the problem. The compiler said my input and my output is the same.
Why did this happen?
Requirement:
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
Example1:
Input: ["h","e","l","l","o"]
Output: ["o","l","l","e","h"]
Example2:
Input: ["H","a","n","n","a","h"]
Output: ["h","a","n","n","a","H"]
Here is my JS:
var reverseString = function(str) {
var nowArray = [];
nowArray.push(str);
var newArray = [];
for(let i=nowArray.length-1, k=0; i>=0; i--, k++) {
newArray[k] = nowArray[nowArray.length-1];
nowArray.length--;
}
console.log(newArray);
};
reverseString( ["h","e","l","l","o"]) // Should return["o","l","l","e","h"]

You donot need to push() str in nowArray. This will make it like this
[["h","e","l","l","o"]]
You can directly set it to nowArray
var reverseString = function(str){
var nowArray=str;
var newArray=[];
for(let i=nowArray.length-1,k=0;i>=0;i--,k++){
newArray[k]=nowArray[nowArray.length-1];
nowArray.length--;
}
console.log(newArray);
};
reverseString( ["h","e","l","l","o"])//Should return["o","l","l","e","h"]
Use the following in leetcode
var reverseString = function(s) {
for(let i = 0;i<Math.floor(s.length/2);i++){
let temp = s[i];
s[i] = s[s.length - 1 - i]
s[s.length - 1 - i] = temp;
}
};

I'm guessing you need the answer as an array, hence the forced string to array.
You could make the code simpler:
var reverseString = function(str){
var newStr = [];
for(var i in str) {
newStr.unshift(str[i]);
}
return newStr;
};

You're pushing the entire string to the nowArray instead of the individual characters. Instead just do var nowArray = str.split("") to get an array of characters.
var reverseString = function(str) {
var nowArray = str.split("");
var newArray = [];
for (let i = nowArray.length - 1, k = 0; i >= 0; i--, k++) {
newArray[k] = nowArray[nowArray.length - 1];
nowArray.length--;
}
console.log(newArray);
};
reverseString("hello");
Also, you were passing an array of characters instead of a string to the reverseString function.
Additionally, since you're splitting the string into the nowArray, you can eliminate the second array, and just use that one. This also lets you cut the iterations in half.
var reverseString = function(str) {
var nowArray = str.split("");
for (let i = nowArray.length - 1, k = 0; i > k; i--, k++) {
[nowArray[i], nowArray[k]] = [nowArray[k], nowArray[i]];
}
console.log(nowArray);
};
reverseString("hello");

Jacky, you can also modify the array in place without taking up additional memory. This takes the original string and swaps the values of the two endpoints. Make sure that you quit the loop at str.length/2 otherwise you will get the exact same array. Furthermore, since you are changing the original input, you do not need to return anything since js passes the arguments by reference.
var reverseString = function(str){
for(let i = 0; i < str.length/2; i++){
// you can swap like this ES6
[str[i],str[str.length-i-1]] = [str[str.length-i-1],str[i]];
// or like this
//var tmp = str[i];
//str[i] = str[str.length-i-1]];
//str[str.length-i-1]] = tmp;
}
console.log(str);
};
reverseString( ["h","e","l","l","o"])//Should return["o","l","l","e","h"]

Related

Looping through array using splice method infinite loop javascript

When i loop through the array using the splice method, the page just freezes. It looks like i caused an infinite loop. lib.randomInt() works, so that is not the problem.
function() {
return function(string) {
var arr = string.split("")
arr.sort();
for(var i = 0; arr.length;i++){
arr.splice((i+1),0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
}
})()("example");
This is from a different file that is placed above the main file in html
var lib = {
factorial: function(num){
function _factorial(num){
if(num === 1){
return 1;
} else {
return num*_factorial(num-1);
}
}
console.log(num+"! = " + _factorial(num));
},
randomInt: function(int,offset){
if(offset == undefined || null || NaN){
offset = 0;
}
return Math.floor(Math.random()*int)+offset;
},
display: function(m, fn){
fn(m);
}
};
You've got to loop in reverse when modifying the array itself to avoid corrupting the loop like this...
for (var i=arr.length-1; i>=0; i--){}
I guess that you wanted to insert a random value after every array element, so that the string "example" would become something like "e5x9a2m4p7l1e3"
There are two issues:
Your for loop has no end condition that will become false. You need to state i < arr.length instead of just arr.length which is always truthy for non-empty arrays.
You add array elements in every iteration, but then also visit them in the next iteration, and from there on you will only be visiting the new inserted values and never get to the next original element that keeps being 1 index away from i. You need to increment i once more. For that you can use ++i instead if i+1 as the splice argument.
So your loop should be:
for(var i = 0; i < arr.length; i++) {
arr.splice(++i,0,lib.randomInt(9));
}
const lib = { randomInt: n => Math.floor(Math.random()*n) };
(function() {
return function(string) {
var arr = string.split("")
arr.sort();
for(var i = 0; i < arr.length; i++) {
arr.splice(++i,0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
console.log(pseudocryptarr);
}
})()("example");
Or to save an addition:
for(var i = 1; i <= arr.length; i+=2) {
arr.splice(i,0,lib.randomInt(9));
}
const lib = { randomInt: n => Math.floor(Math.random()*n) };
(function() {
return function(string) {
var arr = string.split("")
arr.sort();
for(var i = 1; i <= arr.length; i+=2) {
arr.splice(i,0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
console.log(pseudocryptarr);
}
})()("example");
I fixed it. I wanted after each character for there to be a number. Using the pre-looped array length and doubling it while iterating twice, means that the splice adds the number after the new number element and then the character.
Edit: My typo was the problem. I didnt even have to use len, just iterate by 2.
for(var i = 0;i < arr.length;i+=2){
arr.splice((i+1),0,lib.randomInt(9));
}
(function() {
return function(string) {
var arr = string.split("")
arr.sort();
var len = arr.length
for(var i = 0;i < len*2;i+=2){
arr.splice((i+1),0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
console.log(pseudocryptarr);
}
})()("example");
Edit: user4723924 method is better:
(function() {
return function(string) {
var arr = string.split("")
arr.sort();
for(var i = arr.length;i >= 0;i--){
arr.splice((i+1),0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
console.log(pseudocryptarr);
}
})()("example");

Javascript - TypeError: newString.push is not a function

I'm attempting to accept a string (str) as input and then return that string in reverse. (right now it will return an array because I haven't converted the output to a string) My issue is that I keep getting the error TypeError: newString.push is not a function. I declared newString as an array and am attempting to push elements into it. I don't understand what I'm doing wrong.
function FirstReverse(str) {
var newString = [ ];
var eachLetter = str.split("");
for(i = eachLetter.length; eachLetter.length >= 0; i - 1){
newString =+ newString.push(eachLetter[i]);
}
return newString;
}
newString = + something
The arithmetic operation will turn newString into a number.
You don't need to re-assign newString after push at all.
newString.push(eachLetter[i]) // append to newString
Easier way to reverse a string:
"something".split("").reverse().join("")
To fix your problem:
eachLetter.length >= 0 <- this causes an infinite loop, should be i >= 0
i you should start at eachLetter.length - 1, the last index
do not reassign the newString array
you should update the value of i if you don't want an infinite loop, i = i - 1
don't return an array, join the elements to produce a string
function FirstReverse(str) {
var newString = [];
var eachLetter = str.split("");
for (i = eachLetter.length - 1; i >= 0; i = i - 1){
newString.push(eachLetter[i]);
}
return newString.join("");
}
You're assigning (actually adding) to newString the result of newResult.push().
About Array.push(), the return value is a number and it modifies the original array. (Array.push())
You also have some trouble in the (infinite) for loop..
Finally, you're returning an array, not a string.
Try this modification:
function FirstReverse(str) {
var newString = [ ];
var eachLetter = str.split("");
for(i = eachLetter.length - 1; i >= 0; i--){
newString.push(eachLetter[i]);
}
return newString.join("");
}
You can avoid using arrays:
function FirstReverse(str) {
var i, rev = "";
for(i = str.length - 1; i >= 0; i--) rev += str[i];
return rev;
}

How to get the positions of an specified char?

I have a string "Hello World". I want the positions of the char "l" from the String.
My code is the following:
str = "Hello World";
pos = str.search(/l/g);
out.value = pos;
The result of this code is 2, but the wanted result is 2,3,9.
How can i get this result?
Edit: thanks for your help.
But now i want to get the sum of (2+1*105) + (3+1*105) + (9+1*105).
Can you help me again?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec
Finding successive matches
If your regular expression uses the "g" flag, you can use the exec()
method multiple times to find successive matches in the same string.
When you do so, the search starts at the substring of str specified by
the regular expression's lastIndex property (test() will also advance
the lastIndex property).
var str = "Hello World";
var re = /l/g;
var matches = [];
while(match=re.exec(str)) matches.push(match.index);
document.write(matches);
What about a small function to do it?
str = "Hello World";
find = (function(str,c){
results = []
for(i=0;i<str.length;i++){
if (str[i].toLowerCase()===c)
results.push(i)
}
return results
});
find(str,'l')
Here the working fiddle: http://jsfiddle.net/bx8sj0gv/
The position is two, because there is no loop here, so your search will only hit once, which will only display "2" in this case.
You will need to create and array of chars and loop through it like this:
input_1 = [ "hello", "world" ];
for(var i=0; i<input_1.length; i++){
pos = str.search(/l/g);
out.value = pos;
}
This is merely an example, but it will help you understand the concept of it all.
Try this:
var str="Hello World";
var needle='l';
var temp=[];
for(var i=0; i < str.lengt
if(str[i]===haystack){
temp.push(i)
}
}
console.log(temp);
Your code finds only the first instance of the letter and then returns. You need to list over every character of the string like so:
str = "Hello World"
for (var i = 0, len = str.length; i < len; i++) { if(str[i] == "l")
{ console.log(i );
}
}
Here is a link which done this
Finding all indexes of a specified character within a string
var str = "scissors";
var indices = [];
for(var i=0; i<str.length;i++) {
if (str[i] === "s") indices.push(i);
}
While loop solution:
var indices = function(find, where) {
var arr = [];
for (var i = 0, l = where.length; l > i; i++)
if (find === where[i])
arr.push(i);
return arr;
};
alert(indices("l", "Hello World")); // [2, 3, 9]
Recursive solution:
var indices = function(find, where) {
var i = where.lastIndexOf(find);
if (-1 === i) return [];
return indices(find, where.substr(0, i)).concat([i]);
};
alert(indices("l", "Hello World")); // [2, 3, 9]

Remove duplicate commas and extra commas at start/end with RegExp in Javascript, and remove duplicate numbers?

Assume we have a string like the following :
,34,23,4,5,634,23,12,5,4,3,1234,23,54,,,,,,,123,43,2,3,4,5,3424,,,,,,,,123,,,1234,,,,,,,45,,,56
How can we convert it to the following string with RegExp in Javascript ?
34,23,4,5,634,12,3,1234,54,123,43,2,3424,45,56
Actually, I wanna remove repeated items and first and last , char
[edited] To turn these into a set of unique numbers, as you are actually asking for, do this:
function scrapeNumbers(string) {
var seen = {};
var results = [];
string.match(/\d+/g).forEach(function(x) {
if (seen[x]===undefined)
results.push(parseInt(x));
seen[x] = true;
});
return results;
}
Demo:
> scrapeNumbers(',1,22,333,22,,333,4,,,')
[1, 22, 333, 4]
If you had an Array.prototype.unique() primitive, you could write it like so in one line:
yourString.match(/\d+/g).map(parseBase10).unique()
Unfortunately you need to be a bit verbose and define your own parseBase10 = function(n){return parseInt(n)} due to this ridiculous hard-to-track-down bug: javascript - Array#map and parseInt
No need for regex. Few tricks
text = ',34,23,4,5,634,23,12,5,4,3,1234,23,54,,,,,,,123,43,2,3,4,5,3424,,,,,,,,123,,,1234,,,,,,,45,,,56';
text = text.replace(/,+/g, ','); //replace two commas with one comma
text = text.replace(/^\s+|\s+$/g,''); //remove the spaces
textarray = text.split(","); // change them into array
textarray = textarray.filter(function(e){ return e.length});
console.log(textarray);
// Now use a function to make the array unique
Array.prototype.unique = function(){
var u = {}, a = [];
for(var i = 0, l = this.length; i < l; ++i){
if(this[i] in u)
continue;
a.push(this[i]);
u[this[i]] = 1;
}
return a;
}
textarray = textarray.unique();
text = textarray.join(','); //combine them back to what you want
console.log(text);
Demo
If you are familier with jQuery
text = text.replace(/,+/g, ',');
text = $.trim(text);
text = $.unique(text.split(",")).filter(function(e){ return e.length}).join(",");
console.log(text);
Demo
This will do it:
function arrIndex(fnd, arr) {
for (var len = arr.length, i = 0; i < len; i++) {
if (i in arr && arr[i] === fnd) {
return i;
}
}
return -1;
}
function scrapeNumbers(str) {
var arr = str.replace(/,+/g, ",").replace(/^,/, "").replace(/,$/, "").split(",");
for (var i = 0, len = arr.length, rtn = []; i < len; i++) {
if (i in arr && arrIndex(arr[i], rtn) == -1) {
rtn.push(arr[i]);
}
}
return rtn.join(",");
}
var str = ",,34,23,4,5,634,23,12,5,4,3,1234,23,54,,,,,,,123,43,2,3,4,5,3424,,,,,,,,123,,,1234,,,,,,,45,,,56,,";
alert(scrapeNumbers(str));
Here is a jsFiddle
Note: I created a custom array.indexOf function for a better browser support

Remove prefix from a list of strings

How can I remove a sub-string (a prefix) from a array of string elements? (remove the sub string from each element)
Using RegExp and ^ to ensure it is the prefix and not just somewhere in the string:
var arr = ['a1', 'a2', 'a54a'];
for(var i = 0, len = arr.length; i < len; i++) {
arr[i] = arr[i].replace(/^a/, '');
}
arr; // '1,2,54a' removing the 'a' at the begining
function trimPrefix(str, prefix) {
if (str.startsWith(prefix)) {
return str.slice(prefix.length)
} else {
return str
}
}
var prefix = "DynamicPrefix"
trimPrefix("DynamicPrefix other content", prefix)
Many of the answers already given are wrong, because they'll remove the target string from anywhere in each of the elements (not just the beginning). Here's another approach:
var str = "str_";
["str_one", "str_two_str_", "str_three"].map(function(el) {
return el.replace(new RegExp("^" + str), '');
});
Result:
["one", "two_str_", "three"]
Or, if you prefer simple iteration (with no higher-order function):
var str = "str_";
var list = ["str_one", "str_two_str_", "str_three"];
for (var i = 0; i < list.length; i++)
list[i] = list[i].replace(new RegExp("^" + str), '');
var pre = 'prefix_';
my_arr = my_arr.map(function(v){ return v.slice(pre.length); });
See MDN if full browser support for .map() is needed.
you can also use .forEach() if you need to keep the original array.
var pre = 'prefix_';
my_arr.forEach(function(v,i){ my_arr[i] = v.slice(pre.length); });
var i;
for(i = 0; i < arr.length; i++)
arr[i] = arr[i].replace(substr, '');
Example:
var arr = ['test1', '2test', '3test3'];
// Use only one of these lines
var substr = 'test'; // This is for substrings
var substr = /^test/; // This is for prefixes only
var i;
for(i = 0; i < arr.length; i++)
arr[i] = arr[i].replace(substr, '');
console.log(arr); // Prints ["1", "2", "33"] to console
Just for some variety:
substr = new RegExp('(^|\|)prefix_', 'g');
arr = arr.join('|').replace(substr, '').split('|')
edit - to show how you can limit to just the prefix with the right regexp.
Just iterate on your list of string (with a for loop for example) and use the replace method (details here)
Simply loop through them?
var list = ["foo", "bar", "meh"];
for(var i = 0; i < list.length; i++)
list[i] = list[i].substr(1, 1);
http://jsfiddle.net/DcvE2/1/
You could use the jQuery map function -
var arr = $.map(['a1', 'a2'],function (s) {
return s.replace(/^a/,'');
});
I would do this:
var element = document.getElementsByTagName('p');
for(i in element){
str = element[i].innerHTML;
str = str.replace(/^pre_/,'');
element[i].innerHTML = str;
}

Categories

Resources