Palindrome Index HackerRank JS - javascript

I am currently trying to solve the HackerRank Palindrome Index challenge. https://www.hackerrank.com/challenges/palindrome-index/problem
My function seems to be returning "undefined" instead of the solution (the index that should be changed for the string to become a palindrome. Why?
function palindromeIndex(s) {
// Write your code here
const reverse = (string) => s.split("").reverse().join("");
var reversed = reverse(s);
if (reversed === s) {
return -1;
} else {
for (let i = 0; i < s.length; i++) {
// splice the array to remove index i and then compare
let myArray = s.split("");
if ((myArray.splice(i, 1).join("")) === reverse(myArray.splice(i, 1).join(""))) {
return i;
}
} ;
}
}
console.log(palindromeIndex("racezcar"));

Your reverse function is always operating on the same input parameter s to the function, because the local parameter of the reverse function would be called string. Thus, whenever you are calling reverse(something) you are getting back the original input reversed.
You seem to have a misunderstanding on how Array.splice works.
it works in place ie modifies the array you call it on
it returns the removed elements and not the modified array
In your case, it seems easier to use substr instead of splice ...
function palindromeIndex(s) {
// Write your code here
const reverse = (string) => string.split("").reverse().join("");
if (s === reverse(s)) {
return -1;
} else {
for (let i = 0; i < s.length; i++) {
let spliced = s.substr(0, i) + s.substr(i+1);
if (spliced === reverse(spliced))
return i;
}
}
//return whatever specified, when the input can't be
//converted into a palindrome ...
}
console.log(palindromeIndex("racezcar"));
console.log(palindromeIndex("racezcars"));
This code still returns undefined when there is no way to turn the input into a palindrome,

The reason your function is returning undefined is due to your reverse function. There is a minor mistake where you call s instead of string:
const reverse = (string) => s.split("").reverse().join("");
should be changed to:
const reverse = (string) => string.split("").reverse().join("");
Otherwise, you still have a bit of work to do to get it working as expected.

Related

Looking for a function that takes three arguments (x, y, z) and checks if the type of all three is a string

Don't know what to put before the for loop. Don't know if I need an if/else statement. Trying to have it display in the console if items in an array are strings. So I know I need consol.log
var stringOne = isString('rob','bob','carl')
function isString() {
//I dont know what to put before for loop
for(let i = 0; i < arguments.length; i++) {
// Dont know if i need an if/else statement
// Trying to have it display in the console if items in an array are strings
// So I know I need consol.log
}
}
every would be appropriate here, and doing I/O (like console.log) is better left outside of the function. The name of the function suggests that it should return a boolean (true/false):
function isString(...args) {
return args.every(s => typeof s === "string");
}
console.log(isString('rob','bob','carl'));
Because it seems like you're a beginner, I will expand upon the code that you currently have, although #trincot did the best solution.
In a for loop, you can return a value so the loop won't continue. Because you only need to check if any of them are false, may it be in position 0, 1 or 2 in the array, you can return "false" immediately.
If there are only strings, the loop will continue until it ends, and then return "true" at the end of the method.
So you don't need any code before the for loop, only an if statement that returns "false" if any of the items in the array isn't a string.
var stringOne = isString('rob','bob','carl')
var stringTwo = isString('rob','bob', 1)
function isString() {
for(let i = 0; i < arguments.length; i++) {
if (typeof arguments[i] != 'string') {
return false
}
}
return true
}
console.log({stringOne});
console.log({stringTwo});
Something like this in the loop ought to do it:
this_arg = arguments[i];
if (typeof this_arg === 'string') console.log("arg number " + i + " is a string");
It shows how to do it a bit here
You may find every useful here. It iterates over the array you've made from the arguments and checks to see if each element matches the condition. If they all match it returns true, otherwise false.
function isString() {
return Array.from(arguments).every(str => {
return typeof str === 'string';
});
}
console.log(isString('rob','bob','carl'));
console.log(isString(2,'bob','carl'));

i'm trying to use a for..loop to describe the .endsWith() method

I'm basically trying to write a function which when called, performs the action of the endsWith() method
I've tried iterating through the original string and the string to be tested using for loops
function confirmEnding(str, target) {
let strWord = '';
let targetWord = '';
for (let i = (target.length - 1); i >= 0; i--) {
targetWord.concat(target.charAt(i))
for (let j = (str.length - 1); j >= 0; j--) {
strWord.concat(str.charAt(j));
}
}
if (strWord == targetWord) {
return true
} else {
return false
}
}
Now anytime i call the function, it returns true, what's wrong with my code?
concat returns the new string.
Use strWord += whatever; instead.
Primarily, what's wrong with it is that you're using nested loops. There's no need to do that.
The simple, easy way (other than using endsWith!) is to grab the end of str (using the length of target), then compare that substring against target:
function confirmEnding(str, target) {
return str.length >= target.length && str.slice(-target.length) === target;
}
Re your actual code:
concat doesn't modify the string you call it on, it returns a new string (it has to; strings are immutable [unchangeable] in JavaScript)
If you fix #1, your outer loop just copies target to targetWord but in reverse order. Your inner loop copies str to strWord in reverse order repeatedly, so you'll end up with target.length copies of it in strWord.
Nothing in the function tries to take only part of str (the last part, with the same length as target). You end up comparing the full strings (if you fix #1 and #2), not the substring at the end of str.
Finally, just a side note: Any time you find yourself writing:
if (a == b) {
return true;
} else {
return false;
}
you can more concisely and idiomatically write
return a == b;
which does exactly the same thing. :-)

How to get length of string in javascript without using native length method

I am working on a practice problem:
Return the length of a string without using javascript's native string.length method.
The only ways I could think of would be substring or slice, but I'm stumped.
You can loop over the string, testing to see whether there is a non-undefined value at each index (as soon as you get an undefined value you've run past the end of the string):
function strLength(s) {
var length = 0;
while (s[length] !== undefined)
length++;
return length;
}
console.log(strLength("Hello")); // 5
console.log(strLength("")); // 0
(I'm assuming that if you're not allowed to use the native string .length property that you probably shouldn't use the array .length property either with str.split("").length...)
Given that this is a practice problem, I suspect the OP may not want ES6/ES2015, but, just in case that's an option, and/or for whoever else is looking at this, here's a concise modern approach:
const str = "Hello world!";
console.log([...str].reduce(a => a+1, 0));
(When I posted this, no other answer had proposed this solution. However, I had missed the fact that #MarkoGrešak had essentially proposed this exact solution in a comment to another question.)
You can use spread element, Array.prototype.keys() iterator, Array.prototype.pop()
var str = "abc";
var len = [...[0,...str].keys()].pop();
console.log(len, str.length);
The briefest have been able to achieve so far using Object.keys(), Array.prototype.pop() and checking for empty string. Approach could probably be improved further.
var len = str === "" ? 0 : +Object.keys(str).pop()+1;
#nnnnnnn utilizes the two methods at above far exceeding the initial attempt in brevity and addressing case of empty string.
var len = +Object.keys(str+' ').pop();
One way would be iterating through a split string like so:
var count = 0;
Array.from("string here".split("")).forEach(function(){count++});
Tip from Marko below in the comments to use the reduce function to shorten it to:
var count = Array.from("string here".split("")).reduce(function(count){return count+1}, 0);
You could use array.length so you answer the question not using the native string.length.
var Str = "Hello world!";
const CountAr = Str.split("").length;
console.log(CountAr);
/*12*/
function stringLength(str) {
var count = 0;
var index = 0;
while(string[index] !== undefined){
count += 1;
index += 1;
}
return count;
}
I think this will work. If you start with '', it won't go into the while loop, and you'll just return 0.
function getStringLength(string) {
var idx = 0;
while (string[idx] !== undefined) {
idx += 1;
}
return idx;
}
This will work.
function length(str) {
str = str.split('');
var length = 0;
str.forEach(function(element) {
length++;
});
return length;
}
length('hello'); // output 5
Yet another way to do it
function getStringLength(str){
var count = 0;
for(var letter in str){
count += 1;
}
return count;
}
console.log(getStringLength('Mississippi')) // 11
console.log(getStringLength('')) // 0
The for in loop is the way to go I think. You can use slice or substring but for in loops can count strings easily too.
function getStringLength(string) {
var length = 0;
for (var i in string){
length++;
}
return length;
}
This is the solution I came up with
I have used a while loop for getting the length of the input
Sharing Two approaches with a while loop
Approach no 1
function getLength(input) {
if(!input){
return 'please provide input'
}
let i = 0;
while (true) {
if (input[i]) {
i += 1
}else{
break
}
}
return i
}
console.log(getLength([1, 5, 3, 7, 8])) // 5
console.log(getLength("Hare Krishna")) // 12
Output
5 (for array)
12 (for string)
Approach no 2
function getLength(input){
let i = 0;
while(input[i] !== undefined){
i++;
}
return i
}
console.log(getLength([1,2,3,48,8,9])) // 6
Output
6 (for array)
function getStringLength(string) {
// Do NOT use any native 'length' methods.
// You might consider using 'substring' or 'slice' as alternatives.
let i = 0;
while (Number(string.slice(i, i+1)) !== 0) {
i++;
} return i;
}
var output = getStringLength('hello');
console.log(output); // --> 5

In Javascript, how do I check if an array has duplicate values?

Possible Duplicate:
Easiest way to find duplicate values in a javascript array
How do I check if an array has duplicate values?
If some elements in the array are the same, then return true. Otherwise, return false.
['hello','goodbye','hey'] //return false because no duplicates exist
['hello','goodbye','hello'] // return true because duplicates exist
Notice I don't care about finding the duplication, only want Boolean result whether arrays contains duplications.
If you have an ES2015 environment (as of this writing: io.js, IE11, Chrome, Firefox, WebKit nightly), then the following will work, and will be fast (viz. O(n)):
function hasDuplicates(array) {
return (new Set(array)).size !== array.length;
}
If you only need string values in the array, the following will work:
function hasDuplicates(array) {
var valuesSoFar = Object.create(null);
for (var i = 0; i < array.length; ++i) {
var value = array[i];
if (value in valuesSoFar) {
return true;
}
valuesSoFar[value] = true;
}
return false;
}
We use a "hash table" valuesSoFar whose keys are the values we've seen in the array so far. We do a lookup using in to see if that value has been spotted already; if so, we bail out of the loop and return true.
If you need a function that works for more than just string values, the following will work, but isn't as performant; it's O(n2) instead of O(n).
function hasDuplicates(array) {
var valuesSoFar = [];
for (var i = 0; i < array.length; ++i) {
var value = array[i];
if (valuesSoFar.indexOf(value) !== -1) {
return true;
}
valuesSoFar.push(value);
}
return false;
}
The difference is simply that we use an array instead of a hash table for valuesSoFar, since JavaScript "hash tables" (i.e. objects) only have string keys. This means we lose the O(1) lookup time of in, instead getting an O(n) lookup time of indexOf.
You could use SET to remove duplicates and compare, If you copy the array into a set it will remove any duplicates. Then simply compare the length of the array to the size of the set.
function hasDuplicates(a) {
const noDups = new Set(a);
return a.length !== noDups.size;
}
One line solutions with ES6
const arr1 = ['hello','goodbye','hey']
const arr2 = ['hello','goodbye','hello']
const hasDuplicates = (arr) => arr.length !== new Set(arr).size;
console.log(hasDuplicates(arr1)) //return false because no duplicates exist
console.log(hasDuplicates(arr2)) //return true because duplicates exist
const s1 = ['hello','goodbye','hey'].some((e, i, arr) => arr.indexOf(e) !== i)
const s2 = ['hello','goodbye','hello'].some((e, i, arr) => arr.indexOf(e) !== i);
console.log(s1) //return false because no duplicates exist
console.log(s2) //return true because duplicates exist
Another approach (also for object/array elements within the array1) could be2:
function chkDuplicates(arr,justCheck){
var len = arr.length, tmp = {}, arrtmp = arr.slice(), dupes = [];
arrtmp.sort();
while(len--){
var val = arrtmp[len];
if (/nul|nan|infini/i.test(String(val))){
val = String(val);
}
if (tmp[JSON.stringify(val)]){
if (justCheck) {return true;}
dupes.push(val);
}
tmp[JSON.stringify(val)] = true;
}
return justCheck ? false : dupes.length ? dupes : null;
}
//usages
chkDuplicates([1,2,3,4,5],true); //=> false
chkDuplicates([1,2,3,4,5,9,10,5,1,2],true); //=> true
chkDuplicates([{a:1,b:2},1,2,3,4,{a:1,b:2},[1,2,3]],true); //=> true
chkDuplicates([null,1,2,3,4,{a:1,b:2},NaN],true); //=> false
chkDuplicates([1,2,3,4,5,1,2]); //=> [1,2]
chkDuplicates([1,2,3,4,5]); //=> null
See also...
1 needs a browser that supports JSON, or a JSON library if not.
2 edit: function can now be used for simple check or to return an array of duplicate values
You can take benefit of indexOf and lastIndexOf. if both indexes are not same, you have duplicate.
function containsDuplicates(a) {
for (let i = 0; i < a.length; i++) {
if (a.indexOf(a[i]) !== a.lastIndexOf(a[i])) {
return true
}
}
return false
}
If you are dealing with simple values, you can use array.some() and indexOf()
for example let's say vals is ["b", "a", "a", "c"]
const allUnique = !vals.some((v, i) => vals.indexOf(v) < i);
some() will return true if any expression returns true. Here we'll iterate values (from the index 0) and call the indexOf() that will return the index of the first occurrence of given item (or -1 if not in the array). If its id is smaller that the current one, there must be at least one same value before it. thus iteration 3 will return true as "a" (at index 2) is first found at index 1.
is just simple, you can use the Array.prototype.every function
function isUnique(arr) {
const isAllUniqueItems = input.every((value, index, arr) => {
return arr.indexOf(value) === index; //check if any duplicate value is in other index
});
return isAllUniqueItems;
}
One nice thing about solutions that use Set is O(1) performance on looking up existing items in a list, rather than having to loop back over it.
One nice thing about solutions that use Some is short-circuiting when the duplicate is found early, so you don't have to continue evaluating the rest of the array when the condition is already met.
One solution that combines both is to incrementally build a set, early terminate if the current element exists in the set, otherwise add it and move on to the next element.
const hasDuplicates = (arr) => {
let set = new Set()
return arr.some(el => {
if (set.has(el)) return true
set.add(el)
})
}
hasDuplicates(["a","b","b"]) // true
hasDuplicates(["a","b","c"]) // false
According to JSBench.me, should preform pretty well for the varried use cases. The set size approach is fastest with no dupes, and checking some + indexOf is fatest with a very early dupe, but this solution performs well in both scenarios, making it a good all-around implementation.
function hasAllUniqueChars( s ){
for(let c=0; c<s.length; c++){
for(let d=c+1; d<s.length; d++){
if((s[c]==s[d])){
return false;
}
}
}
return true;
}

How can I check JavaScript arrays for empty strings?

I need to check if array contains at least one empty elements. If any of the one element is empty then it will return false.
Example:
var my_arr = new Array();
my_arr[0] = "";
my_arr[1] = " hi ";
my_arr[2] = "";
The 0th and 2nd array elements are "empty".
You can check by looping through the array with a simple for, like this:
function NoneEmpty(arr) {
for(var i=0; i<arr.length; i++) {
if(arr[i] === "") return false;
}
return true;
}
You can give it a try here, the reason we're not using .indexOf() here is lack of support in IE, otherwise it'd be even simpler like this:
function NoneEmpty(arr) {
return arr.indexOf("") === -1;
}
But alas, IE doesn't support this function on arrays, at least not yet.
You have to check in through loop.
function checkArray(my_arr){
for(var i=0;i<my_arr.length;i++){
if(my_arr[i] === "")
return false;
}
return true;
}
You can try jQuery.inArray() function:
return jQuery.inArray("", my_arr)
Using a "higher order function" like filter instead of looping can sometimes make for faster, safer, and more readable code. Here, you could filter the array to remove items that are not the empty string, then check the length of the resultant array.
Basic JavaScript
var my_arr = ["", "hi", ""]
// only keep items that are the empty string
new_arr = my_arr.filter(function(item) {
return item === ""
})
// if filtered array is not empty, there are empty strings
console.log(new_arr);
console.log(new_arr.length === 0);
Modern Javascript: One-liner
var my_arr = ["", "hi", ""]
var result = my_arr.filter(item => item === "").length === 0
console.log(result);
A note about performance
Looping is likely faster in this case, since you can stop looping as soon as you find an empty string. I might still choose to use filter for code succinctness and readability, but either strategy is defensible.
If you needed to loop over all the elements in the array, however-- perhaps to check if every item is the empty string-- filter would likely be much faster than a for loop!
Nowadays we can use Array.includes
my_arr.includes("")
Returns a Boolean
You could do a simple help method for this:
function hasEmptyValues(ary) {
var l = ary.length,
i = 0;
for (i = 0; i < l; i += 1) {
if (!ary[i]) {
return false;
}
}
return true;
}
//check for empty
var isEmpty = hasEmptyValues(myArray);
EDIT: This checks for false, undefined, NaN, null, "" and 0.
EDIT2: Misread the true/false expectation.
..fredrik
function containsEmpty(a) {
return [].concat(a).sort().reverse().pop() === "";
}
alert(containsEmpty(['1','','qwerty','100'])); // true
alert(containsEmpty(['1','2','qwerty','100'])); // false
my_arr.includes("")
This returned undefined instead of a boolean value so here's an alternative.
function checkEmptyString(item){
if (item.trim().length > 0) return false;
else return true;
};
function checkIfArrayContainsEmptyString(array) {
const containsEmptyString = array.some(checkEmptyString);
return containsEmptyString;
};
console.log(checkIfArrayContainsEmptyString(["","hey","","this","is","my","solution"]))
// *returns true*
console.log(checkIfArrayContainsEmptyString(["yay","it","works"]))
// *returns false*
yourArray.join('').length > 0
Join your array without any space in between and check for its length. If the length, turns out to be greater than zero that means array was not empty. If length is less than or equal to zero, then array was empty.
I see in your comments beneath the question that the code example you give is PHP, so I was wondering if you were actually going for the PHP one? In PHP it would be:
function hasEmpty($array)
{
foreach($array as $bit)
{
if(empty($bit)) return true;
}
return false;
}
Otherwise if you actually did need JavaScript, I refer to Nick Craver's answer
Just do a len(my_arr[i]) == 0; inside a loop to check if string is empty or not.
var containsEmpty = !my_arr.some(function(e){return (!e || 0 === e.length);});
This checks for 0, false, undefined, "" and NaN.
It's also a one liner and works for IE 9 and greater.
One line solution to check if string have empty element
let emptyStrings = strArray.filter(str => str.trim().length <= 0);
let strArray = ['str1', '', 'str2', ' ', 'str3', ' ']
let emptyStrings = strArray.filter(str => str.trim().length <= 0);
console.log(emptyStrings)
One line solution to get non-empty strings from an array
let nonEmptyStrings = strArray.filter(str => str.trim().length > 0);
let strArray = ['str1', '', 'str2', ' ', 'str3', ' ']
let nonEmptyStrings = strArray.filter(str => str.trim().length > 0);
console.log(nonEmptyStrings)
If you only care about empty strings then this will do it:
const arr = ["hi","hello","","jj"]
('' in arr) //returns false
the last line checks if an empty string was found in the array.
I don't know if this is the most performant way, but here's a one liner in ES2015+:
// true if not empty strings
// false if there are empty strings
my_arr.filter(x => x).length === my_arr.length
The .filter(x => x) will return all the elements of the array that are not empty nor undefined. You then compare the length of the original array. If they are different, that means that the array contains empty strings.
You have to check in through the array of some functions.
if isEmptyValue is true that means the array has an empty string otherwise not.
const arr=['A','B','','D'];
const isEmptyValue = arr.some(item => item.trim() === '');
console.log(isEmptyValue)
array.includes("") works just fine.
Let a = ["content1", "" , "content2"];
console.log(a.includes(""));
//Output in console
true

Categories

Resources