1

I've successfully converted this php spintax code into javascript, source from http://www.edcharkow.com/blog/spintax-easy-php-code/

But some times the repeated the results are way too often, and I'm thinking to check the last spun spintax with the result, if it's true, it should continue spinning.

Now my problem is, how do I create a new instance off that Spin(s) function as the last spun result everytime I perform a spin?

I maybe approaching this problem in the most straightforward manner, but would love to hear any better alternative if there's such.

var text = "{{this|that} is {nice|awesome|great}!|What {are you|am I} doing?|I can't believe {this|that} is {happening|so awesome!}}";

alert( Spin(text) );

function Spin(s)
{
    var m = s.match(/\{(.*?)\}/i);
    if ( !m ) return s;

    var t = m[1];

    if ( t.indexOf("{") !== false )
    {
        t = t.substr(t.lastIndexOf("{") + 1);
    }

    var parts = t.split("|");

    var regex = new RegExp("\{" + preg_quote(t) + "\}");
    s = s.replace( regex, parts[Math.floor(Math.random() * parts.length)] );

    return Spin(s);
}

function preg_quote(str, delimiter) 
{
  return String(str).replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
}
Randize
  • 121
  • 1
  • 10
  • Have you tried any code to compare two runs of Spin(text) ? – Michael Paulukonis May 02 '14 at 03:24
  • 1
    Thanks for the reply @MichaelPaulukonis I never have thought to compare 2 `Spin()` My current workaround is using 2 constructor parameters for the `Spin()` function like `spin(str, lastStr)` I'll post an answer, but I really think there's a better way doing this. – Randize May 02 '14 at 07:20
  • I quickly gave it a thought, my... your solution is much more simpler @MichaelPaulukonis I was making it harder by thinking to compare the result within the function itself. `lastSpun; spun = Spin(text); while ( spun == lastSpun) { spun = Spin(text); } alert(spun); lastSpun = spun;` Cheers mate! – Randize May 02 '14 at 07:38

2 Answers2

0

Since I can't set 2 variables to compare the last spun text with just a single construct parameter in the function. I resort to putting 2 parameters in. It feel dirty tho, but it works. I'd still appreciate anyone who'd be willing to provide better alternatives.

lastSpun = Spin(text, text);

// Spintax
function Spin(s, u)
{
    var m = s.match(/\{(.*?)\}/i);
    if ( !m ) 
    {
        // If spun text is not equal to the last spun text, return the new spun text
        // Else reset the new spun text back into spintax text and spin again
        if ( lastSpun !== s ) { return s; } else { s = u; return Spin(s, u); }
    }

    var t = m[1];

    if ( t.indexOf("{") !== false )
    {
        t = t.substr(t.lastIndexOf("{") + 1);
    }

    var parts = t.split("|");

    var regex = new RegExp("\{" + preg_quote(t) + "\}");
    s = s.replace( regex, parts[Math.floor(Math.random() * parts.length)] );

    // This will loop the spintax until every {nested} elements are chosen
    return Spin(s, u);
}
Randize
  • 121
  • 1
  • 10
  • Keep the Spin function as it is -- no need to dirty it up. Use a wrapper-method supplied with the previous output to do a comparison and call-until-new. See my answer @ http://stackoverflow.com/a/23428635/41153 – Michael Paulukonis May 02 '14 at 13:19
0

Keep things simple - the Spin function should generate spun text, and nothing else. Use some other function to do what you want.

Here's a quick wrapper to compare runs:

var prev = "";

var getNewSpun = function(prevSpun) {
     var newspun = Spin(text);   
     while (newspun == prevSpun) {
       newspun = Spin(text);   
     }
     return newspun; 
};


prev = getNewSpun(prev); // this should be different every time
Michael Paulukonis
  • 9,020
  • 5
  • 48
  • 68