Check if string contains substring without using indexOf - Javascript - javascript

My function is trying to check if string contains substring without use of indexOf or regex match or any standard JS methods.
Please check this jsfiddle: https://jsfiddle.net/09x4Lpj2/
var string1 = 'applegate';
var string2 = 'gate';
function containsString(string1, string2){
var j = 0;
var k = 0;
var contains = 'false';
var charArray1 = string1.split('');
var charArray2 = string2.split('');
for(var i = 0; i < charArray2.length; i++){
j = i;
if(charArray1[j++] != charArray2[k++]){
contains = 'false';
}else{
contains = 'true';
}
}
console.log(contains);
}
containsString(string1, string2);
This solution works only when the indexes are the same between the two strings (ex. applegate and apple). But will not work if the indexes are not the same (ex. applegate and gate). How do I manipulate the iterative values correctly so that the function returns true for both situations?

you can try this modified script of yours.
var string1 = 'applegate';
var string2 = 'gate';
var string3 = 'apple';
var string4 = 'leg';
var string5 = 'banana';
function containsString(string1, string2){
var charArray1 = string1.split('');
var charArray2 = string2.split('');
var match = 0;
// iterate from start of 1st string until length of 1st string minus length of 2nd string
// you don't need to iterate the last part that is not longer than 2nd string since it will be false
for(var i = 0; i < charArray1.length - charArray2.length + 1; i++){
// reset match counter on every iteration
match = 0;
// iterate the 2nd string
for(var j = 0; j < charArray2.length; j++){
// compare corresponding char location
if(charArray1[i+j] == charArray2[j]){
match++;
// just to check in console
console.log(i, j, match, charArray1[i+j], charArray2[j]);
} else {
// just to check in console
console.log(i, j, match, charArray1[i+j], charArray2[j]);
// if not match, just skip current check
break;
}
// if match already found, stop the checks, and return true
if(match == charArray2.length){
return true;
}
}
}
// match not found until end of iteration
return false;
}
console.log(containsString(string1, string2));
console.log(containsString(string1, string3));
console.log(containsString(string1, string4));
console.log(containsString(string1, string5)); // haystack does not contain needle
console.log(containsString(string4, string1)); // haystack is shorter than needle

Welcome to SO.
Regex can be used.. Unless even that is also prohibited..
function containsString(string1, string2){
console.log(string1.match(string2) != null ? "Yes" : "No");
}
Regex

This code has a logical problem,Only to determine whether the last character of A is equal to the corresponding character of B,Maybe the following code is what you want,add a line of code.
var string1 = 'applegate';
var string2 = 'gate';
function containsString(string1, string2){
var j = 0;
var k = 0;
var contains = 'false';
var charArray1 = string1.split('');
var charArray2 = string2.split('');
for(var i = 0; i < charArray2.length; i++){
j = i;
if(charArray1[j++] != charArray2[k++]){
contains = 'false';
break;
}else{
contains = 'true';
}
}
console.log(contains);
}

Check this without using any inbuilt functions
function subSearch(long,short){
var count = 0
for(i = 0;i < long.length; i++){
for(j = 0;j < short.length; j++){
if(short[j] != long[i + j]){
break;
}
if((j+1) == short.length){
count++;
}
}
}
return count;
}

Related

How can I extract all contained characters in a String? [duplicate]

I have a string with repeated letters. I want letters that are repeated more than once to show only once.
Example input: aaabbbccc
Expected output: abc
I've tried to create the code myself, but so far my function has the following problems:
if the letter doesn't repeat, it's not shown (it should be)
if it's repeated once, it's show only once (i.e. aa shows a - correct)
if it's repeated twice, shows all (i.e. aaa shows aaa - should be a)
if it's repeated 3 times, it shows 6 (if aaaa it shows aaaaaa - should be a)
function unique_char(string) {
var unique = '';
var count = 0;
for (var i = 0; i < string.length; i++) {
for (var j = i+1; j < string.length; j++) {
if (string[i] == string[j]) {
count++;
unique += string[i];
}
}
}
return unique;
}
document.write(unique_char('aaabbbccc'));
The function must be with loop inside a loop; that's why the second for is inside the first.
Fill a Set with the characters and concatenate its unique entries:
function unique(str) {
return String.prototype.concat.call(...new Set(str));
}
console.log(unique('abc')); // "abc"
console.log(unique('abcabc')); // "abc"
Convert it to an array first, then use Josh Mc’s answer at How to get unique values in an array, and rejoin, like so:
var nonUnique = "ababdefegg";
var unique = Array.from(nonUnique).filter(function(item, i, ar){ return ar.indexOf(item) === i; }).join('');
All in one line. :-)
Too late may be but still my version of answer to this post:
function extractUniqCharacters(str){
var temp = {};
for(var oindex=0;oindex<str.length;oindex++){
temp[str.charAt(oindex)] = 0; //Assign any value
}
return Object.keys(temp).join("");
}
You can use a regular expression with a custom replacement function:
function unique_char(string) {
return string.replace(/(.)\1*/g, function(sequence, char) {
if (sequence.length == 1) // if the letter doesn't repeat
return ""; // its not shown
if (sequence.length == 2) // if its repeated once
return char; // its show only once (if aa shows a)
if (sequence.length == 3) // if its repeated twice
return sequence; // shows all(if aaa shows aaa)
if (sequence.length == 4) // if its repeated 3 times
return Array(7).join(char); // it shows 6( if aaaa shows aaaaaa)
// else ???
return sequence;
});
}
Using lodash:
_.uniq('aaabbbccc').join(''); // gives 'abc'
Per the actual question: "if the letter doesn't repeat its not shown"
function unique_char(str)
{
var obj = new Object();
for (var i = 0; i < str.length; i++)
{
var chr = str[i];
if (chr in obj)
{
obj[chr] += 1;
}
else
{
obj[chr] = 1;
}
}
var multiples = [];
for (key in obj)
{
// Remove this test if you just want unique chars
// But still keep the multiples.push(key)
if (obj[key] > 1)
{
multiples.push(key);
}
}
return multiples.join("");
}
var str = "aaabbbccc";
document.write(unique_char(str));
Your problem is that you are adding to unique every time you find the character in string. Really you should probably do something like this (since you specified the answer must be a nested for loop):
function unique_char(string){
var str_length=string.length;
var unique='';
for(var i=0; i<str_length; i++){
var foundIt = false;
for(var j=0; j<unique.length; j++){
if(string[i]==unique[j]){
foundIt = true;
break;
}
}
if(!foundIt){
unique+=string[i];
}
}
return unique;
}
document.write( unique_char('aaabbbccc'))
In this we only add the character found in string to unique if it isn't already there. This is really not an efficient way to do this at all ... but based on your requirements it should work.
I can't run this since I don't have anything handy to run JavaScript in ... but the theory in this method should work.
Try this if duplicate characters have to be displayed once, i.e.,
for i/p: aaabbbccc o/p: abc
var str="aaabbbccc";
Array.prototype.map.call(str,
(obj,i)=>{
if(str.indexOf(obj,i+1)==-1 ){
return obj;
}
}
).join("");
//output: "abc"
And try this if only unique characters(String Bombarding Algo) have to be displayed, add another "and" condition to remove the characters which came more than once and display only unique characters, i.e.,
for i/p: aabbbkaha o/p: kh
var str="aabbbkaha";
Array.prototype.map.call(str,
(obj,i)=>{
if(str.indexOf(obj,i+1)==-1 && str.lastIndexOf(obj,i-1)==-1){ // another and condition
return obj;
}
}
).join("");
//output: "kh"
<script>
uniqueString = "";
alert("Displays the number of a specific character in user entered string and then finds the number of unique characters:");
function countChar(testString, lookFor) {
var charCounter = 0;
document.write("Looking at this string:<br>");
for (pos = 0; pos < testString.length; pos++) {
if (testString.charAt(pos) == lookFor) {
charCounter += 1;
document.write("<B>" + lookFor + "</B>");
} else
document.write(testString.charAt(pos));
}
document.write("<br><br>");
return charCounter;
}
function findNumberOfUniqueChar(testString) {
var numChar = 0,
uniqueChar = 0;
for (pos = 0; pos < testString.length; pos++) {
var newLookFor = "";
for (pos2 = 0; pos2 <= pos; pos2++) {
if (testString.charAt(pos) == testString.charAt(pos2)) {
numChar += 1;
}
}
if (numChar == 1) {
uniqueChar += 1;
uniqueString = uniqueString + " " + testString.charAt(pos)
}
numChar = 0;
}
return uniqueChar;
}
var testString = prompt("Give me a string of characters to check", "");
var lookFor = "startvalue";
while (lookFor.length > 1) {
if (lookFor != "startvalue")
alert("Please select only one character");
lookFor = prompt(testString + "\n\nWhat should character should I look for?", "");
}
document.write("I found " + countChar(testString, lookFor) + " of the<b> " + lookFor + "</B> character");
document.write("<br><br>I counted the following " + findNumberOfUniqueChar(testString) + " unique character(s):");
document.write("<br>" + uniqueString)
</script>
Here is the simplest function to do that
function remove(text)
{
var unique= "";
for(var i = 0; i < text.length; i++)
{
if(unique.indexOf(text.charAt(i)) < 0)
{
unique += text.charAt(i);
}
}
return unique;
}
The one line solution will be to use Set. const chars = [...new Set(s.split(''))];
If you want to return values in an array, you can use this function below.
const getUniqueChar = (str) => Array.from(str)
.filter((item, index, arr) => arr.slice(index + 1).indexOf(item) === -1);
console.log(getUniqueChar("aaabbbccc"));
Alternatively, you can use the Set constructor.
const getUniqueChar = (str) => new Set(str);
console.log(getUniqueChar("aaabbbccc"));
Here is the simplest function to do that pt. 2
const showUniqChars = (text) => {
let uniqChars = "";
for (const char of text) {
if (!uniqChars.includes(char))
uniqChars += char;
}
return uniqChars;
};
const countUnique = (s1, s2) => new Set(s1 + s2).size
a shorter way based on #le_m answer
let unique=myArray.filter((item,index,array)=>array.indexOf(item)===index)

How to extract longest word from an array? JavaScript/JSON

I want to create a function that takes a string as its parameter and extracts the longest word. If there are multiple words of the same length (max), It extracts the first one. (By the way, the function ignores numbers and punctuation). Anyways, here's the code:
function extractLongest(testString){
var lenArr = [];
var finalResult = "";
window.onload = function(){
testString = testString.replace(/[^a-z " "]/gi, '');
testString = testString.split(" ");
for (var counter = 0; counter < testString.length; counter++){
lenArr[counter] = parseInt(testString[counter].length);
}
lenArr = lenArr.sort();
for (var counterTwo = 0; counterTwo < testString.length; counterTwo++){
if(parseInt(testString[counterTwo].length) == Math.max(...lenArr)){
finalResult = testString[counterTwo];
break;
}
}
}
return finalResult;
}
The problem is that it always returns "string" (the type of the variable, not its value.)
The problem is your use of window.onload inside a function. This is only setting the handler on the window, which will only run when an onload event fires. Your function does this and then immediately returns finalReuslts which will still be an empty string. Presumably, you want all this code to run when you call the function. It's not clear why you are doing that; removing it makes the function work:
function extractLongest(testString){
var lenArr = [];
var finalResult = "";
testString = testString.replace(/[^a-z " "]/gi, '');
testString = testString.split(" ");
for (var counter = 0; counter < testString.length; counter++){
lenArr[counter] = parseInt(testString[counter].length);
}
lenArr = lenArr.sort();
for (var counterTwo = 0; counterTwo < testString.length; counterTwo++){
if(parseInt(testString[counterTwo].length) == Math.max(...lenArr)){
finalResult = testString[counterTwo];
break;
}
}
return finalResult;
}
console.log(extractLongest("hello my name is stephen"))
In case it's useful, there is a simpler way to do this with reduce():
function extractLongest(testString){
testString = testString.replace(/[^a-z " "]/gi, '');
testString = testString.split(" ");
return testString.reduce(function(a, b) {
return a.length > b.length ? a : b
});
}
console.log(extractLongest("hello my designation is stephen"))

Javascript: I am trying to loop through a string of characters and determine if a character is missing

this is my challenge: Create a function that will find the missing letter passed in the parameter and return it. If all letters are present in the string, the return will be undefined. For example missingLetter("abce") should return "d", missingLetter("bcd") should return undefined.
I am having trouble with this one, can you please tell me if I am on the right track with my code:
var missingLetter = function(char){
var missing = "";
var str = "abcdefghijklmnopqrstuvwxyz";
for (var i = char[0]; i < char.length; i++){
for(var y = char[0].indexOf(str); y < char.length; y++ ){
if(char[y].indexOf(str) == -1 ){
missing.push(char[y]);
}
}
}
console.log(missing);
return missing;
}
missingLetter("abce")
Tonmoy already give the answer if you want you can check this. First if you want to use push function then you must create a array.
var missingLetter = function(char){
var missing = []
var y = 0
var str = "abcdefghijklmnopqrstuvwxyz";
for (var i = 0; i < str.length; i++){
while(y < char.length ){
if( char[y] != str[y+i] ){
missing.push(str[y+i])
++i
}
else
++y
}
}
console.log(missing)
return missing
}
missingLetter("cdz")
you have defined variable missing as string, but It should be a array(). The loop condition is not properly. Following is the code snippet, which works fine.
var missingLetter = function(char){
var missing = new Array();
var str = "abcdefghijklmnopqrstuvwxyz";
var i = 0;
while(i<char.length) {
for(var j=0;j<26;j++) {
if(str[j].indexOf(char[i])>-1){
i++;
} else {
missing.push(str[j]);
}
}
}
console.log(missing);
return missing;
}
missingLetter("abce");

error in cloned substring() function in js

I am trying to make a function in js that checks whether a substring exists in main string. For eg:- main = 111010 and substring = 011 should return false as substring does not exists in main string but my code returns true. Here is the code below.
var string = "111010",
substr = "011";
var found=false;
outter:for(var i=0;i<string.length;i++){
if(string.charAt(i)==substr.charAt(0)){
var k=i+1;
inner:for(j=1;j<substr.length;j++){
if(string.charAt(k++)==substr.charAt(j)){
found=true;
continue inner;
}else{
continue outter;
}
}
}
}
if(found!=false){
console.log("y")
}else{
console.log("n");
}
You forget to re-initialize the found variable.
var string = "111010",
substr = "0110";
var found=false;
for(var i=0;i<string.length;i++){
if(string.charAt(i)==substr.charAt(0)){
var k=i+1;
for(j=1; j < substr.length;j ++)
if(string.charAt(k++)==substr.charAt(j)){
found=true;
}else{
found = false; // <<--this
break;
}
if(found) break;
}
}
if(found!=false){
console.log("y")
}else{
console.log("n");
}
Your code always returns true if it ever find a single common letter between your string and substring.
And please, DO NOT USE LABELS, they are simply bad. Thanks!
Demo: http://jsfiddle.net/fer52ufd/
Here is how your code should actually be.
var found = false;
for (var i = 0; i < string.length; i++) { // starting position
found = true; // All letters match, prove the opposite
for (j = 0; j < substr.length; j++) { // Compare the given string with the string starting at i
if (string.charAt(i + j) != substr.charAt(j)) { // If one letter does not match, stop searching
found = false;
break;
}
}
if (found) break;
}
Why treat the first letter separately?
Don't use labels
Don't search for the match, search for letters that do not match and, if you find none, the strings match.
Do not use unnecessary index variables (as k), the position of the letter on the needle string is j and in the hay string is i+j
This is the code to check that:
var string = "111010", substr = "011";
var test = string.indexOf(substr);
if (test >= 0) {
alert('yes');
} else {
alert('no');
}

Test if input values match constant value

Ive got an assignment and am a bit stuck.
Need to match an input string to the values in a constant, but I am matching individual characters.
My constant would be ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUWXYZ'
My input would be, var input = 'ABOZ'
I need a test to check if each letter in the input variable exist in the ALPHABET constant.
Hope I made sense.
Cheers
Here's a single line answer to your question:
(ALPHABET.match(new RegExp((input.split('').join('|')), 'g'))).length == input.length
which would return true only if all the characters in input are present in ALPHABET
Here's a working demo http://jsfiddle.net/kayen/akL4A/
One way is to loop over the input and search if it exits in the constant
Possible code
var ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUWXYZ';
var input = 'ABOZ'
var count = 0;
for(x in input) {
if(ALPHABET.indexOf(input[x])>-1){
count++;
continue;
}
else{
break;
}
}
if(count==input.length) {
alert("true");
}
Demo
Tested and works in Firefox 16. Remember this implementation does not verify if input is null or other defensive checks. You should do it by yourself.
This is a case sensitive result.
Case insensitive :
function validInput(input) {
var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUWXYZ";
for (var i = 0; i < input.length; i++) {
var charAtI = input.charAt(i);
var indexOfCharAtI = ALPHABET.indexOf(charAtI);
if (indexOfCharAtI < 0) {
return false;
}
}
return true;
}
Case insensitive :
function validInput(input) {
var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUWXYZ";
for (var i = 0; i < input.length; i++) {
var charAtI = input.charAt(i);
charAtI = charAtI.toUpperCase();
var indexOfCharAtI = ALPHABET.indexOf(charAtI);
if (indexOfCharAtI < 0) {
return false;
}
}
return true;
}
Here's an example of a function which would return true for a match or false for a mismatch. (Please note this is a case sensitive test).
var ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var input = 'ABOZ';
function testStr(str, constant){
var matchFlag = true;
var strSplit = str.split("");
for(var i=0; i<strSplit.length;i++){
if(constant.indexOf(strSplit[i]) == -1){
matchFlag = false;
}
}
return matchFlag;
}
alert(testStr(input, ALPHABET)); //TRUE
DEMO

Categories

Resources