Solved

Javascript to detect repeated characters

Posted on 2003-11-20
17
696 Views
Last Modified: 2013-12-03
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
Comment
Question by:Barry62
  • 5
  • 5
  • 3
  • +4
17 Comments
 
LVL 10

Expert Comment

by:NetGroove
ID: 9790671
Give an example and the expected result.
0
 
LVL 15

Expert Comment

by:JakobA
ID: 9790800
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
 
LVL 31

Expert Comment

by:GwynforWeb
ID: 9790826
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
 
LVL 31

Expert Comment

by:GwynforWeb
ID: 9790966
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
 
LVL 15

Expert Comment

by:JakobA
ID: 9791040
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
 
LVL 8

Author Comment

by:Barry62
ID: 9791080
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
 
LVL 31

Expert Comment

by:GwynforWeb
ID: 9791089
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
 
LVL 8

Author Comment

by:Barry62
ID: 9791170
Also, I need to keep track of the repeated letter I've already used.
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 31

Expert Comment

by:GwynforWeb
ID: 9791207
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
 
LVL 1

Expert Comment

by:cj_nepenthe
ID: 9791306
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
 
LVL 15

Expert Comment

by:JakobA
ID: 9791441
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
 
LVL 8

Author Comment

by:Barry62
ID: 9796933
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
 
LVL 31

Expert Comment

by:GwynforWeb
ID: 9801126
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
 
LVL 8

Author Comment

by:Barry62
ID: 9810788
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
 
LVL 16

Expert Comment

by:jaysolomon
ID: 10383199
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
 
LVL 8

Author Comment

by:Barry62
ID: 10383626
That's fine, thanks.
0
 

Accepted Solution

by:
SpazMODic earned 0 total points
ID: 10420413
PAQed, with points refunded (250)

SpazMODic
EE Moderator
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Suggested Solutions

Avoid defining the variables in the global scope; trying to define them in a local function scope. Because:   • Look-up is performed every time a variable is accessed.   • Variables are resolved backwards from most specific to least specific scope…
In Part 1 (http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/A_7849-Hex-Maze.html) we covered the hexagonal maze basics -- how the cells are represented in a JavaScript array and how the maze is displayed.  In this part, we'…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now