2

这是那些看起来应该很容易的 ColdFusion 事情之一......但我没有找到简单的路径。

我有一个列表数组。数组可以是任意大小,每个列表的长度可以是任意大小。(这可以被操纵成一个多维数组,无论如何......重点是,我有一个列表列表)

例如

  1. 129,128,127

  2. 130,131,132

  3. 135,133,134

  4. 137,138,136

  5. 140,139

  6. 141,142

或者一个简短的版本......它可能会有所不同

  1. 13,14,15

  2. 11,12

我需要的是一个数组、查询或其他包含所有可能唯一组合的数据结构,按顺序从每个列表中取一个......所以对于简短版本,将有 6 个唯一组合。对于第一个较长的示例,我们将有 3*3*3*3*2*2 = 324 个唯一组合。

计算它们很容易......但是以结构化格式获得实际组合的最佳方法是什么?一定缺少一些简单的东西......我已经很接近几个小时了!:-/

4

3 回答 3

5

这是我的看法。归功于codingforums.com上这篇文章中的php函数:http: //www.codingforums.com/showpost.php? p= 945289&postcount =3 我刚刚想出了如何在cfml中重新编写它。

<cfscript>
public array function array_cartesian_product(_arrays=[]) {
    var result = [];
    var _arrayslen = arraylen(arguments._arrays);
    var _size = (_arrayslen) ? 1 : 0;
    var _array = '';
    var x = 0;
    var i = 0;
    var j = 0;
    var _current = [];

    for (x=1; x lte _arrayslen; x++) {
        _size = _size * arraylen(arguments._arrays[x]);
        _current[x] = 1;
    }

    for (i=1; i lte _size; i++) {
        result[i] = [];

        for (j=1; j lte _arrayslen; j++) {
            arrayappend(result[i], arguments._arrays[j][_current[j]]);
        }

        for (j=_arrayslen; j gt 0; j--) {
            if (arraylen(arguments._arrays[j]) gt _current[j])  {
                _current[j]++;
                break;
            }
            else {
                _current[j] = 1;
            }
        }

    }

    return result;
}
</cfscript>
<cfset arrays = [[129,128,127],[130,131,132],[135,133,134],[137,138,136],[140,139],[141,142]]>
<cfset r = array_cartesian_product(arrays)>
<cfoutput>#arraylen(r)#</cfoutput>
<cfdump var="#r#">
于 2012-04-06T12:49:29.463 回答
1

像这样的东西应该工作。循环遍历第一个列表中的每个项目,并与列表 2 和 3 中的每个项目进行组合,然后检查以确保其不在已知列表中,如果没有,则将其添加到组合列表中。

<cfset list1 = "1,2,3" />
<cfset list2 = "4,5,6" />
<cfset list3 = "7,8,9,1" />

<cfset combinations = [] />

<cfloop list="#list1#" index="i">
  <cfif not arrayFind(combinations,i)>
    <cfset arrayAppend(combinations,i) />
  </cfif>
  <cfloop list="#list2#" index="y">
    <cfif not arrayFind(combinations,y)>
      <cfset arrayAppend(combinations,y) />
    </cfif>
    <cfif not arrayFind(combinations, "#i#,#y#")>
      <cfset arrayAppend(combinations,"#i#,#y#") />
    </cfif>
    <cfloop list="#list3#" index="z">
       <cfif not arrayFind(combinations,z)>
         <cfset arrayAppend(combinations,z) />
       </cfif>
       <cfif not arrayFind(combinations, "#i#,#y#,#z#")>
         <cfset arrayAppend(combinations,"#i#,#y#,#z#") />
      </cfif>
    </cfloop>
  </cfloop>
</cfloop>

<cfdump var="#combinations#" />
于 2012-04-06T12:27:00.673 回答
0

好的,所以您需要遍历列表数组。在每次迭代中,您需要针对每个剩余列表遍历该位置的列表。

所以在位置一迭代 2 3 4 5 6 在位置二迭代 3 4 5 6 依此类推

于 2012-04-06T10:25:35.843 回答