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');
}
Related
Function that returns the first letter that is present in both strings that a user submits via
an input type text, the strings are separated with a comma. For example:aaaaa,bbbbba--> the matching letter is 'a'because is present in both strings
Sorry for some italian names but i code in italian
I'm not sure how to continue, i have a for to go throught both strings, but i'm not sure if it's correct
function Ripetizione() {
var rip = document.getElementById("string").value;
if (rip.indexOf(",") == -1) { //check to see if the comma is not present
alert("Non c'è nessuna virgola");
return;
}
var stringa1 = rip.substr(0, rip.indexOf(",")); //this is the string1 before the comma
var stringa2 = rip.substr(rip.indexOf(",") + 1, rip.length - (stringa1.length + 1)); //this is the second string after the comma
for (i = 0; i <= stringa1.length; i++) { //for cycle to count the elements of the first string
}
for (k = 0; i <= stringa2.lenght; k++) { //same for the string2
}
}
Ripetizione()
You need not loop the second string.. Just check for index of the element => 0 , while looping through each element of first string part. And return the value..
Always prefer functional over imperative programming.Use Array#find
function getCommonLetter(str){
const [stringA, stringB]=str.split(',');
return Array.from(stringB).find(val => stringA.includes(val));
}
console.log(getCommonLetter('ab,ba'))
console.log(getCommonLetter('ads,bsd'))
console.log(getCommonLetter('aaa,bbc'))
function Ripetizione() {
var rip=document.getElementById("string").value;
if (rip.indexOf(",")==-1){
alert("Non c'è nessuna virgola");
return;
}
var stringa1=rip.substr(0,rip.indexOf(","));
var stringa2=rip.substr(rip.indexOf(",")+1,rip.length-(stringa1.length+1));
return search(stringa1, stringa2);
}
function search(a, b){
for(var i=0; i<a.length;i++){
for(var j=0;j<b.length;j++){
if(a[i] == b[j]){
return a[i];
}
}
}
}
We can do it using Array#reduce and check for the presence of the matching chars using Array#includes.
The idea is to convert the strings into an array of string using Array#from then use the reduce function to match and accumulate the matched characters.
//returns the matching chars as an array
function Ripetizione(rip) {
//let rip=document.getElementById("string").value;
let strs = rip.split(",");
if (strs.length !== 2){ //check to see if the comma is not present
alert("Non c'è nessuna virgola");
return;
}
//converting strings to array to use reduce
let strOne = Array.from(strs[0]), strTwo = strs[1];
return strOne.reduce((acc,alpha)=> {
return !acc.includes(alpha) && strTwo.includes(alpha)?[alpha,...acc]:acc;
},[]).slice(0,1).toString();
}
console.log(Ripetizione("aaaaaab,bbbbba"));
console.log(Ripetizione("aaaaaa,bbbbba"));
console.log(Ripetizione("acccaaaa,bbbbba"));
console.log(Ripetizione("acccaaaa,bbbbcba"));
console.log(Ripetizione("dddddddd,bbbbba")); //return blank string
console.log(Ripetizione("ab,ba"));
function Ripetizione() {
var rip = document.getElementById("string").value;
if (rip.indexOf(",") == -1) { //check to see if the comma is not present
alert("Non c'è nessuna virgola");
return;
}
var stringa1 = rip.substr(0, rip.indexOf(",")); //this is the string1 before the comma
var stringa2 = rip.substr(rip.indexOf(",") + 1, rip.length - (stringa1.length + 1)); //this is the second string after the comma
if (stringa1.length <= stringa2.length) {
stringa2 = stringa2.split('')
stringa1 = stringa1.split('')
for (i = 0; i <= stringa2.length; i++) { //for cycle to count the elements of the first string
if (stringa1.includes(stringa2[i])) {
console.log(stringa2[i]);
}
}
} else if (stringa1.length >= stringa2.length) {
stringa1 = stringa1.split('')
stringa2 = stringa2.split('')
for (i = 0; i <= stringa1.length; i++) { //for cycle to count the elements of the first string
if (stringa2.includes(stringa1[i])) {
console.log(stringa1[i]);
}
}
}
}
<input id="string" type="text">
|<button id="ok" onclick="Ripetizione()">done</button>
The following demo binds the change event to input. When a user enters text in input then clicks outside of input the function is called. The function uses split() and filter() and displays the result in an output. The function also removes any spaces and reports if there are no matches as well.
Demo
Details are commented in demo
var str = document.getElementById("string");
// This is an Event Handler
function ripZ(e) {
var result = document.getElementById('result');
var rip = this.value;
if (rip.indexOf(",") === -1) {
result.value = "Separate the two strings with a comma (no spaces).";
return;
}
// If there's a space remove it
var rip = rip.replace(/\s/g, '');
// Split the string at the comma making an array of two strings
var array = rip.split(',');
/*
Take each string and split them at each letter.
Now there's two arrays of letters
*/
var first = array[0].split('');
var second = array[1].split('');
/*
Loop through both arrays by using two for...of loops
*/
var match = first.filter(function(f, i) {
return second.indexOf(f) !== -1;
});
// Display results
if (match) {
result.innerHTML = `
The letter "${match[0]}" is the first match between both strings.`;
} else {
result.value = "There was no match."
}
return;
}
/*
This is an onevent property registered to the input
If a user types into the input then clicks outside of input
the Event Handler ripZ() is called.
*/
str.onchange = ripZ;
<input id='string'><button>GO</button><br>
<output id='result'></output>
If the input was "ab,ba", you sad that it should be return b so Code must be above in my openion :
function Ripetizione() {
// var rip=document.getElementById("string").value;
// if (rip.indexOf(",")==-1){
// alert("Non c'è nessuna virgola");
// return;
// }
// var stringa1=rip.substr(0,rip.indexOf(","));
// var stringa2=rip.substr(rip.indexOf(",")+1,rip.length-(stringa1.length+1));
var stringa1="ab";
var stringa2="ba";
for(var i=0; i<stringa2.length;i++){
for(var j=0;j<stringa1.length;j++){
if(stringa2.charAt(i) === stringa1.charAt(j)){
console.log(stringa2.charAt(i));
return;
}
}
}
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;
}
I try to match/get all repetitions in a string. This is what I've done so far:
var str = 'abcabc123123';
var REPEATED_CHARS_REGEX = /(.).*\1/gi;
console.log( str.match(REPEATED_CHARS_REGEX) ); // => ['abca', '1231']
As you can see the matching result is ['abca', '1231'], but I excpect to get ['abc', '123']. Any ideas to accomplish that?
2nd question:
Another thing I excpect, is to make it possible to change the duration how often a char needs to be in the string to get matched...
For example if the string is abcabcabc and the repetation-time is set to 2 it should result in ['abcabc']. If set to 3 it should be ['abc'].
Update
A non-RegExp solution is perfectly alright!
Well, I think falsetru had a good idea with a zero-width look-ahead.
'abcabc123123'.match(/(.+)(?=\1)/g)
// ["abc", "123"]
This allows it to match just the initial substring while ensuring at least 1 repetition follows.
For M42's follow-up example, it could be modified with a .*? to allow for gaps between repetitions.
'abc123ab12'.match(/(.+)(?=.*?\1)/g)
// ["ab", "12"]
Then, to find where the repetition starts with multiple uses together, a quantifier ({n}) can be added for the capture group:
'abcabc1234abc'.match(/(.+){2}(?=.*?\1)/g)
// ["abcabc"]
Or, to match just the initial with a number of repetitions following, add the quantifier within the look-ahead.
'abc123ab12ab'.match(/(.+)(?=(.*?\1){2})/g)
// ["ab"]
It can also match a minimum number of repetitions with a range quantifier without a max -- {2,}
'abcd1234ab12cd34bcd234'.match(/(.+)(?=(.*?\1){2,})/g)
// ["b", "cd", "2", "34"]
This solution may be used if you don't want to use regex:
function test() {
var stringToTest = 'find the first duplicate character in the string';
var a = stringToTest.split('');
for (var i=0; i<a.length; i++) {
var letterToCompare = a[i];
for (var j=i+1; j<a.length; j++) {
if (letterToCompare == a[j]) {
console.log('first Duplicate found');
console.log(letterToCompare);
return false;
}
}
}
}
test()
The answer above returns more duplicates than there actually are. The second for loop causes the problem and is unnecessary. Try this:
function stringParse(string){
var arr = string.split("");
for(var i = 0; i<arr.length; i++){
var letterToCompare = arr[i];
var j= i+1;
if(letterToCompare === arr[j]){
console.log('duplicate found');
console.log(letterToCompare);
}
}
}
var duplicateCheck = function(stru) {
var flag = false;
for (let o = 0; o < stru.length; o++) {
for (let p = 0; p < stru.length; p++) {
if (stru.charAt(o) === stru.charAt(p) && o!==p) {
flag = true;
break;
}
}
}
return flag;
}
true ==> duplicate found
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
// Validate Sentence Case
if(dataEntryCaseId.toString().match("4")){
var newValue = toTitleCase(value);
if(newValue != value){
for(var x = 1, j = value.length; x < j; x++){
if(value.charAt(x) != newValue.charAt(x)){
valid = false;
$("#text_10").attr({"value":$("#text_10").attr("value").replace(value.charAt(x), "")});
finalVal = finalVal.replace(value.charAt(x), "");
}
}
}
}
if(!valid){
for(var x = 0, j = styleNoteJsonData.styleGroupNote.length; x < j; x++){
if(styleNoteJsonData.styleGroupNote[x].styleName == styleGroupName){
alert(styleNoteJsonData.styleGroupNote[x].styleNote);
$(".styleNote").addClass("alertRed");
SendErrorMessage(styleNoteJsonData.styleGroupNote[x].styleNote);
}
}
} else {
$(".styleNote").removeClass("alertRed");
}
if(finalVal.length > 0){
return true;
}
return valid;
}
function toTitleCase(str){
return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}).replace(/\s/, '');
}
I need to rework this to only allow the first letter to be capitalized (it doesn't have to be)
I was trying to do this with regex - which i'm not sure is needed if the javascript validation was correct - seefunction toTitleCase(str)
regex seems overkill - but maybe because the current validation is using it, it might be easier to incorporate, but I wanted to see if their were other options within the parameters of the current code.
Your question is not very clear. If you want to only keep the first uppercase, use this function:
function toTitleCase(str){
return str.charAt(0)+str.substring(1).toLowerCase();
}
Additional notes:
Add str = str.replace(/\s/g,""); before return ... when you want to remove all white-space characters.
If you only want to remove the beginning and ending whitespace characters, add str = str.replace(/^\s+/,"").replace(/\s+$/,""); instead,