Subject: Re: [xsl] How to Do Random "Shuffle"? From: "Dimitre Novatchev dnovatchev@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Sat, 13 Sep 2014 16:40:04 -0000 |
This can be done even with XSLT 1.0: http://fxsl.sourceforge.net/articles/Random/Casting%20the%20Dice%20with%20FXS L-htm.htm More specifically, use the FXSL 1 stylesheet module randomList.xsl Here is an existing test (demo): When this transformation (testRandomList.xsl): <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ext="http://exslt.org/common" xmlns:f="http://fxsl.sf.net/" xmlns:mySquare="f:mySquare" xmlns:myDouble="f:myDouble" exclude-result-prefixes="xsl f ext mySquare myDouble" > <xsl:import href="randomList.xsl"/> <xsl:output omit-xml-declaration="yes" indent="yes"/> <!-- This transformation must be applied to: numList.xml --> <mySquare:mySquare/> <myDouble:myDouble/> <xsl:template match="/"> <xsl:variable name="vrtfRands"> <xsl:call-template name="randomSequence"> <xsl:with-param name="pLength" select="100"/> </xsl:call-template> </xsl:variable> Random Recursive Index (dScale (randomSequence 100)): <xsl:call-template name="_dScale"> <xsl:with-param name="pRandSeq" select="ext:node-set($vrtfRands)/*"/> </xsl:call-template> Random Recursive Index 10: <xsl:variable name="vrtfRecIndex"> <xsl:call-template name="_randomRecursiveIndex"> <xsl:with-param name="pList" select="/*/*"/> </xsl:call-template> </xsl:variable> <xsl:variable name="vRecIndex" select="ext:node-set($vrtfRecIndex)/*"/> <xsl:for-each select="$vRecIndex"> <xsl:copy-of select="."/>
 </xsl:for-each> Randomized 10-elements list: <xsl:call-template name="_permutationFromRecursiveIndex"> <xsl:with-param name="pList" select="/*/*"/> <xsl:with-param name="pRecIndex" select="$vRecIndex"/> </xsl:call-template> RandomizeList: <xsl:call-template name="randomizeList"> <xsl:with-param name="pList" select="/*/*"/> </xsl:call-template> <xsl:variable name="vFunSquare" select="document('')/*/mySquare:*[1]"/> _mapFromRandIndex (^2) [1..10] seed: <xsl:call-template name="_mapFromRandIndex"> <xsl:with-param name="pFun" select="$vFunSquare"/> <xsl:with-param name="pList" select="/*/*"/> <xsl:with-param name="pRecIndex" select="$vRecIndex"/> </xsl:call-template> <xsl:variable name="vFunDouble" select="document('')/*/myDouble:*[1]"/> randomMap (*2) [1..10] seed: <xsl:call-template name="randomMap"> <xsl:with-param name="pFun" select="$vFunDouble"/> <xsl:with-param name="pList" select="/*/*"/> </xsl:call-template> randListIndex [1..10] seed: <xsl:call-template name="randListIndex"> <xsl:with-param name="pList" select="/*/*"/> </xsl:call-template> </xsl:template> <xsl:template match="mySquare:*" mode="f:FXSL"> <xsl:param name="arg1"/> <xsl:value-of select="$arg1 * $arg1"/> </xsl:template> <xsl:template match="myDouble:*" mode="f:FXSL"> <xsl:param name="arg1"/> <xsl:value-of select="$arg1 + $arg1"/> </xsl:template> </xsl:stylesheet> is applied on this source XML document: <nums> <num>01</num> <num>02</num> <num>03</num> <num>04</num> <num>05</num> <num>06</num> <num>07</num> <num>08</num> <num>09</num> <num>10</num> </nums> the result is: Random Recursive Index (dScale (randomSequence 100)): <el>27</el> <el>90</el> <el>14</el> <el>78</el> <el>65</el> <el>13</el> <el>27</el> <el>85</el> <el>75</el> <el>33</el> <el>31</el> <el>26</el> <el>9</el> <el>40</el> <el>31</el> <el>80</el> <el>19</el> <el>44</el> <el>52</el> <el>7</el> <el>8</el> <el>73</el> <el>55</el> <el>16</el> <el>68</el> <el>20</el> <el>29</el> <el>4</el> <el>3</el> <el>30</el> <el>51</el> <el>41</el> <el>14</el> <el>32</el> <el>66</el> <el>4</el> <el>19</el> <el>51</el> <el>48</el> <el>59</el> <el>30</el> <el>1</el> <el>49</el> <el>57</el> <el>14</el> <el>53</el> <el>13</el> <el>10</el> <el>10</el> <el>38</el> <el>13</el> <el>37</el> <el>13</el> <el>36</el> <el>22</el> <el>7</el> <el>28</el> <el>25</el> <el>28</el> <el>7</el> <el>29</el> <el>3</el> <el>34</el> <el>28</el> <el>7</el> <el>13</el> <el>14</el> <el>5</el> <el>32</el> <el>25</el> <el>25</el> <el>24</el> <el>8</el> <el>26</el> <el>23</el> <el>14</el> <el>11</el> <el>18</el> <el>15</el> <el>6</el> <el>5</el> <el>6</el> <el>9</el> <el>4</el> <el>8</el> <el>14</el> <el>12</el> <el>12</el> <el>5</el> <el>2</el> <el>5</el> <el>1</el> <el>4</el> <el>1</el> <el>4</el> <el>4</el> <el>1</el> <el>2</el> <el>1</el> <el>1</el> Random Recursive Index 10: <el>3</el> <el>9</el> <el>2</el> <el>6</el> <el>5</el> <el>1</el> <el>2</el> <el>3</el> <el>2</el> <el>1</el> Randomized 10-elements list: <el>03</el> <el>10</el> <el>02</el> <el>08</el> <el>07</el> <el>01</el> <el>05</el> <el>09</el> <el>06</el> <el>04</el> RandomizeList: <el>03</el> <el>10</el> <el>02</el> <el>08</el> <el>07</el> <el>01</el> <el>05</el> <el>09</el> <el>06</el> <el>04</el> _mapFromRandIndex (^2) [1..10] seed: <el>9</el> <el>100</el> <el>4</el> <el>64</el> <el>49</el> <el>1</el> <el>25</el> <el>81</el> <el>36</el> <el>16</el> randomMap (*2) [1..10] seed: <el>6</el> <el>20</el> <el>4</el> <el>16</el> <el>14</el> <el>2</el> <el>10</el> <el>18</el> <el>12</el> <el>8</el> randListIndex [1..10] seed: <el>3</el> <el>10</el> <el>2</el> <el>8</el> <el>7</el> <el>1</el> <el>5</el> <el>9</el> <el>6</el> <el>4</el> The last result gives us a random index of the integers in [1, 10] These indexes can be used to select in a random order 10 nodes. In XSLT 2 one can use the standard XPath function current-time() for the creation of the seed: http://www.w3.org/TR/xpath-functions/#func-current-time Cheers, Dimitre On Sat, Sep 13, 2014 at 7:29 AM, Eliot Kimber ekimber@xxxxxxxxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: > Using XSLT 2 I need to implement rendering of "match table" questions > where you have two sets of items, the match item and the thing it matches > to. I want to present this as a literal table, where the first column is > the match-from items in source order and the second column is the match-to > items, in random order. > > I think this is best characterized as a "shuffle" problem, where you want > to reorder a list randomly but all items in the list must be accounted > for. > > I can think of a recursive algorithm: given a list, generate a random > integer between 1 and the list length, select that item and add it to the > result list, then call this function on the original list minus the node > you just selected. > > Is there an easier or more efficient way to do it? > > Thanks, > > Eliot > bbbbb > Eliot Kimber, Owner > Contrext, LLC > http://contrext.com
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] How to Do Random "Shuffle, Dimitre Novatchev dn | Thread | Re: [xsl] How to Do Random "Shuffle, Eliot Kimber ekimber |
Re: [xsl] How to Do Random "Shuffle, Abel Braaksma (Exsel | Date | Re: [xsl] How to Do Random "Shuffle, Dimitre Novatchev dn |
Month |