2

I'm looking for an eloquent way to mix up the middle characters of words in a string, as in "this is an example string" becomes "tihs is an eplamxe sritng." I'm thinking first separate the words into an array, select words longer than two characters, separating out the first and last letters for the first part, but I can't figure out a good way to scramble them.

Jonas
  • 121,568
  • 97
  • 310
  • 388

6 Answers6

2

Edit Much better answer.

Here's a quick and dirty approach. You can use a regular expression to find all strings at least 3 characters long and pull out the first character, the last character, and the middle characters. Then you simply split the array of middle characters, randomly sort them and join them back together, sticking the first and last characters back on.

myStr.replace(/\b([a-z])([a-z]+)([a-z])\b/ig, function(str, first, middle, last) {
    return first +
           middle.split('').sort(function(){return Math.random()-0.5}).join('') + 
           last;
});
Brian Nickel
  • 26,890
  • 5
  • 80
  • 110
1
function middleMix(s){
    var A= s.split(''), c1= A.shift(), c3= A.pop() || '';
    while(A.length) c1+= A.splice(Math.floor(Math.random()*A.length), 1);
    return c1+c3;
}

This method splits the string into an array of characters, shifts off the first character and pops off the last.

The middle part(if any) is then spliced, one random character at a time, and added to the prefix.

It is returned with the suffix added last.

//edit- multiple words

function middleMix(str){
    var s= str.split(' ');
    for(var i= 0; i<s.length;i++){
        var A= s[i].split(''), c1= A.shift(), c3= A.pop() || '';
        while(A.length) c1+= A.splice(Math.floor(Math.random()*A.length), 1);
        s[i]= c1+c3;
    }
    return s.join(' ');
}

middleMix("this is an example string")

/*  returned value: (String)
tihs is an exmlpae sitrng
*/
kennebec
  • 102,654
  • 32
  • 106
  • 127
  • Just as a note, he wants each word mixed, not the whole string. He would need to split it first and then randomize each section. Finally putting all the sections back together. – mrtsherman Nov 16 '11 at 03:40
  • 1
    Man, why the lame downvote with no explanation? It looks like a great solution to me. Does he have to do all the work for the OP? Example - http://jsfiddle.net/YgMF3/ – mrtsherman Nov 16 '11 at 03:48
0

Version for complete html page. The core is the @kennebec's code, and the input/arguments of function are the list of wanted "textual" HTML tags, between aphostrophes.

I don't understand the '. undefined' errors after some paragraph.. (www.juxta.hu/eng/04.html) but it's working – width in-placed HTML-elements too. eg.

<em>Para<b>graph</b>I.C. etc.</em>

The secret for me is the method of this section's working:

 if (s[i].search("<")==-1)
                        {s[i].split("<*>")

If the splitted word is NOT (==-1) contained any HTML elements (width "<" char), then cut-out that…

.split("<*>")

I was lucky. ?

<script>
    function shuffle() 
    {
        for (var k = 0; k < arguments.length; k++) 
      {                             
            var x = document.getElementsByTagName(arguments[k]);
                for (var n = 0; n < x.length; n++) 
          {
                var s= x[n].innerHTML.split(' ');
                for (var i= 0; i<s.length; i++) 
                    {   if (s[i].search("<")==-1)
                        {s[i].split("<*>");
                            var A= s[i].split(''), c1= A.shift(), c3= A.pop() || '';
                        while(A.length) c1+= A.splice(Math.floor(Math.random()*A.length), 1);
                        s[i]= c1+c3;
                      }
                    }                                               
                    x[n].innerHTML= s.join(' ');
              }
      }
    }

</script>

<body onload='shuffle("p", "a", "li", "h1", "span", "u", "b", "dd", "dt")'>
Ral Dzsi
  • 1
  • 1
0

Write a function that takes an array and shuffles everything between index i and j. You can find examples here

Now from the string identify all pairs of start and end indexes of all words.

Call your shuffle function for all pairs

Community
  • 1
  • 1
parapura rajkumar
  • 24,045
  • 1
  • 55
  • 85
0

Here is some code to do that for you:

var str = 'this is an example string.';

var arr = str.split(/\b/g);
var i, j;
for(i = 0; i < arr.length; i++){
    if(/^\w{4,}$/.test(arr[i])){
        var temp = [];
        var end = arr[i].length - 1;
        for(j = 1; j < end; j++)
            temp.push(arr[i][j]);
        arr[i] = arr[i][0] + shuffle(temp).join('') + arr[i][end];
    }
}
str = arr.join('');

document.write(str);

function shuffle(o){
    for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};

Shuffle function taken from here: http://snippets.dzone.com/posts/show/849

Here you go: http://jsfiddle.net/66LXx/

Paul
  • 139,544
  • 27
  • 275
  • 264
0

This code does the trick,Well yes as you said I have considered finding out string length in if condition but It must be greater than 3 not than 2.

<script type="text/javascript">
 var myString = "hello world" ;         ' some value
 var mySplitResult = myString.split(" ");   ' now split it with space seperator
 var a = mySplitResult.Length();           ' get the lenth of splitted array in a
 var i ;
 var temp;
 var result_string;
 result_string= ""; 
 for(i=0;i<a;i++)
 {
   var k = mysplitResult[i].length();  ' now get the length of each string of array 
   if ( k > 3 )                        ' greater than 3 then enter if block
   {
      mySplitResult = mySplitResult.Reverse()  ' just used reverse function
      temp = mySplitResult[0];             
      mySplitResult[0] = mySplitResult[k-1];  ' then swapped first and last element of the string
      mySplitResult[k-1] = temp;
      result_string = result_string + mySplitResult[i]; ' here is the result string this is what is final output
   }
  else
  {
     result_string = result_string + mySplitResult[i];
  }
 }

</script>
niko
  • 9,285
  • 27
  • 84
  • 131