Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 712
  • Last Modified:

Javascript to detect repeated characters

I need a javascript routine that will detect repeated characters in an array.  The repeated characters are not necessarily next to each other in the array.
0
Barry62
Asked:
Barry62
  • 5
  • 5
  • 3
  • +4
1 Solution
 
NetGrooveCommented:
Give an example and the expected result.
0
 
JakobACommented:
anu chaacter have a numeric value (as in the ascii table) the value may vary with different alphabets but each chaacte vill have its own unique value in whichever alphabet.

we can use that by creating an array where those character values are the indeces in the array:


var inputString = "you put your string into this variable"

function mulChars( str ) {       // find multiple characters in a string
     var  charCount = new Array();    // here we accunulate counts for each character found
     var i = str.length;
     var chCode;
     for (var i=str.length-1; i>=0; i-- ) {
           chCode = str.charCodeAt( i );
           if ( typeof( charCount[chCode] ) == 'undefined' ) {
               charCount[chCode] = 1;                       // first ocurrence of that character
           } else {
               charCount[chCode]++                         // all other ocurrences increas the count
           }
     }
        //  now the array is complete. for any cell in the array the content may be:
        //    undefined            // char with that code was not found in the string
        //    a number             // hov many times that character was found.
     var result = "";
     for (var i=0; i<charCount.length; i++ ) {
           if ( typeof( charCount[i] ) == 'number'  &&  charCount[i] > 1 ) result += String.fromCharCode( i );
     }
     return result;
} // end mulChars

var res = mulChars( inputString );
alert( "The following characters occur more than once: '" +res +"'." );


mvh JakobA
0
 
GwynforWebCommented:
Here we are, easily modified to give the repeating char if you want as well

<script>
function repeats(arr){
found=false
for  (i=0;i<arr.length;i++)
   for (j=i+1;j<arr.length;j++)
      if (arr[i] == arr[j]) found=true
 return(found)
}
chrs1=new Array("a","c","d","t","s","q")
chrs2=new Array("a","c","d","t","w","d","s")
alert(repeats(chrs1))
alert(repeats(chrs2))
</script>
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
GwynforWebCommented:
Here is the code giving the repeats as well

<script>

function repeats(arr){
found=false
reps=" "
for  (i=0;i<arr.length;i++)
   for (j=i+1;j<arr.length;j++)
      if (arr[i] == arr[j])
         {found=true
          reps+=arr[i]
          }
 return(found+reps)
}
chr1=new Array("a","c","z","t","w","d","s")
chr2=new Array("a","c","d","t","w","d","c","a","s")
alert(repeats(chr1))
alert(repeats(chr2))
</script>
0
 
JakobACommented:
GwynforWeb >> try this:

chr1=new Array("a","c","a","t","a","d","s");         // 'a' occur 3 times

alert(repeats(chr1))

I think you wil get a recorded as a repeat twice.
0
 
Barry62Author Commented:
OK, GwynforWeb,

I tried to adapt your code to my program, but it's not working.

Here's what I'm trying to do:

I'm writing a word jumble program in ASP and JavaScript.  I break up a random word(supplied by a table) and populate an ASP array with each separate letter, after randomizing them.

I display the scrambled word and then allow the user to click on each letter, which places the selected letter in the solution area.  The selected letter in the scrambled word then turns red.  If the user clicks on the red letter again, it is erased from the solution.  This works fine until I select a repeated letter.  The program then erase the letter from the solution as if it was the first time I selected it.  

I can populate a JavaScript array from the displayed word, but I need a routine in Javascript that will not erase the previous occurence of the repeated letter.

Barry62
0
 
GwynforWebCommented:
When dealing with strings you can use the fiollowing simple regular expression

<script>
function repTest(s)
  {return ( /(\w).*\1/.test(s) )}


s="acfds_n3"
alert(repTest(s))
s="acfdsn"
alert(repTest(s))
s="acfdsns"
alert(repTest(s))
s="acwwfdsnxxs"
alert(repTest(s))
</script>

0
 
Barry62Author Commented:
Also, I need to keep track of the repeated letter I've already used.
0
 
GwynforWebCommented:
Barry62, I see what you are trying to do, to do it I must know how the words are being displayed, in a table?

0
 
cj_nepentheCommented:
I know it's already been done, but I thought I'd give it a try anyway.  Here's what I came up with, it's a slightly different approach...

var arrSource = new Array('a', 'b', 'a', 'c', 'd', 'a', 'b');
var arrDupes = new Array();
var objHash = new Object();
for (var intIndex in arrSource) {
      var strLetter = arrSource[intIndex];
      if (strLetter in objHash) arrDupes[strLetter] = true;
      else objHash[strLetter] = 1;
}

var arrDupeResults = new Array();
for (strDupe in arrDupes) arrDupeResults.push(strDupe);
alert(arrDupeResults.join(','));
0
 
JakobACommented:
new attempt using an array of characters as input as specified:

// - - - - - - beginning of code

var inputArray = [ 'a', 'l', 'f', 'a', 'b', 'e', 't', ' ', 's', 'o', 'u', 'p' ];  // you set it to whatever

function mulChars( inArr ) {       // find multiple characters in a string
     var outArr = new Array();   // here we accunulate counts for each character found
     var ch;
     for (var i=inArr.length-1; i>=0; i-- ) {
           ch = str.charAt( i );
           if ( outArrt[ch] ) {
               outArr[ch]++                         // all other ocurrences increas the count
           } else {
               outArr[ch] = 1;                      // first ocurrence of that character
           }
     }
     return outArr;
} // end mulChars

var checkArray = mulChars( inputArray );     // checkArray must be remembered

// now we use the generated checkArray to keep track of which letters can be added or should be removed:

function canIAddThis( charStr ) {
    if ( checkArray[ charStr ] ) {
        if ( checkArray[ charStr ] > 0 ) {
            checkArray[ charStr ]--;   //count down
            return true;               // you can add it (I have already done the countdown so you better)
        } else {
            checkArray[ charStr ]++;   // count up
            return false;              // you must remove it (I have already done the countup so you better)
        }
    } else {
        alert( "Serious error. 'canIAddThis' called with a parameter not in the original array." );
    }
}

// - - - - -  end of code

whenever the user click on a letter you call 'canIAddThis' with the chosen letter as parameter. if the function return true add the letter, if it return fals remove it,
    if ( canIAddThis( "a" ) ) {
        // add the letter
        // find an uncolored version of that letter and color it (there will be one)
    } else {
        // remove the letter
        // find an colored version of that letter and uncolor it (there will be one)
    }

regards JakobA
0
 
Barry62Author Commented:
The scrambled word is being displayed as plain text, each letter inside its own span container.  The choices are being displayed in readonly text controls.
0
 
GwynforWebCommented:
I can not do this properly with seeing you code but you can remove a letter in a span by setting the innerHTML to "". The code below might give you some ideas

<form name="ans">
<input type="text" name="l1" size=1>
<input type="text" name="l2" size=1>
<input type="text" name="l3" size=1>
<input type="text" name="l4" size=1>
<input type="text" name="l5" size=1>
</form><p>
<span onClick='document.ans.l2.value=this.innerHTML;this.innerHTML=""'>P</span>
<span onClick='document.ans.l1.value=this.innerHTML;this.innerHTML=""'>S</span>
<span onClick='document.ans.l3.value=this.innerHTML;this.innerHTML=""'>I</span>
<span onClick='document.ans.l5.value=this.innerHTML;this.innerHTML=""'>S</span>
<span onClick='document.ans.l4.value=this.innerHTML;this.innerHTML=""'>T</span>
0
 
Barry62Author Commented:
OK, that would work fine.  However, I am already removing a letter fine when it is re-selected.  Here is my code.  You'll have to run it to see exactly what I'm talking about.


<html>
<head>
      <title>Jumble</title>
<script language="JavaScript">
var corrheight=768;
var corrwidth=1024;
if(screen.width<corrwidth||screen.height<corrheight){
 document.write("<link rel=\"STYLESHEET\" type=\"text/css\" href=\"../tlt_sm.css\">");
}
if(screen.width>=corrwidth||screen.height>=corrheight){
 document.write("<link rel=\"STYLESHEET\" type=\"text/css\" href=\"../tlt.css\">");
}
function focusit(el){
elem= document.getElementById(el);
elem.focus();
newClass(elem);
}
function newClass(elem){
elem.className='hilite';
}
function oldClass(elem){
elem.className='under';
}

function hilite(el){
elem = document.getElementById(el);
elem.className='red';
}
function checkJum(ltr,elnum,jumel){
//alert("'" + ltr + "' " + elnum)
word=new Array(elnum-1);
for(chk = 1;chk <= elnum;chk++){
el = "ltr" + chk;
elem = document.getElementById(el);
jumelement = "jum" + jumel;
jumelem = document.getElementById(jumelement);
for(x=0;x<=elnum;x++){
    word[x]=elem.value;
}    
//alert(ltr + " " + "'" + elem.value + "'")
    if(elem.value == ""){
    if(!repeats(word)){
        elem.value=ltr;
        jumelem.className='red';
        break;
        }
    }
    if(elem.value != ""){
      if(elem.value == ltr){
       
        elem.value="";
        jumelem.className='nostyle';
        break;
       
      }  
    }
}
}
function checkJum2(ltr,numltrs,elnum){
for(chk=1;chk<=numltrs;chk++){
      elname="jum" + chk;
      elementnum=document.getElementById(elname);
      ltrel="ltr" + elnum;
      ltrelement = document.getElementById(ltrel);
      if(ltr == elementnum.value){
        elementnum.className='nostyle';
      }
}
}

function repeats(arr){
found=false
for  (i=0;i<arr.length;i++)
   for (j=i+1;j<arr.length;j++)
      if (arr[i] == arr[j]) found=true
 return(found)
}
</script>
<style>
input{background:#5B386E;border:none;border-bottom:solid #E6BE4C;color:#E6BE4C;font-size:16px;font-family:'Comic Sans MS';width:1em;text-transform:uppercase;}
.hilite{border:solid thin #E6BE4C;}
.under{border:none;border-bottom:solid #E6BE4C;cursor:hand;}
.nostyle{border:none;cursor:hand;}
.red{border:none;color:#FF0000;cursor:hand;}
</style>
</head>    

<body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" style="font-family:'Comic Sans MS';font-size:16px;">
<div align="center">
<%
Set connJumble = Server.CreateObject("ADODB.Connection")
Set cmdJumble = Server.CreateObject("ADODB.Recordset")
connJumble.Open "PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=" & server.mappath("../db/games.mdb") & ";"
wordsSQL = "SELECT * from singles"
cmdJumble.CursorType=3
cmdJumble.open wordsSQL,connJumble
dim wordarray()
dim word1()
arrcnt = 1
      Randomize()
      iRandom1 = Int(cmdJumble.RecordCount * Rnd + 1)
     redim wordarray(cmdJumble.RecordCount)
    while not cmdJumble.eof
    wordarray(arrcnt)=ucase(cmdJumble("word"))
    arrcnt = arrcnt + 1
    cmdJumble.MoveNext
    wend
    redim word1(len(wordarray(iRandom1)))
     one = wordarray(iRandom1)
     'scramble word1
      for x1 = 1 to len(wordarray(iRandom1))
    rndnum1 = Int(len(one) * Rnd + 1)
    word1(x1) = mid(one,rndnum1,1)
    one = mid(one,1,rndnum1-1) & mid(one,rndnum1 + 1,len(one)-rndnum1)
    response.write "<span id=""jum" & x1 & """ class=""nostyle"" onClick=""checkJum('" & word1(x1) & "'," & len(wordarray(iRandom1)) & "," & x1 & ")"">" & word1(x1) & "</span>"
    next
    response.write "<BR><BR>"
    response.write "<BR><BR>"
response.write "<form name='guess' action='jumble.asp' method='post'>"
  for y1 = 1 to len(wordarray(iRandom1))
  if word1(y1) <> " " then
 response.write "<input type=""text"" id='ltr" & y1 & "' style=""width:1em;"" class=""under"" readonly onClick=""checkJum2('" & word1(y1) & "'," & len(wordarray(iRandom1)) & "," & y1 & ")"">&nbsp;" &  vbCrlf
  else
  response.write "&nbsp;&nbsp;&nbsp;"
  end if
  next
  response.write "</form>"
%>
</div>
</body>
</html>
0
 
jaysolomonCommented:
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

PAQ with points refunded

Please leave any comments here within the next four days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

jAy
EE Cleanup Volunteer
0
 
Barry62Author Commented:
That's fine, thanks.
0
 
SpazMODicCommented:
PAQed, with points refunded (250)

SpazMODic
EE Moderator
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 5
  • 5
  • 3
  • +4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now