2012-04-23 34 views
1

我仍然试图让我在Coldfusion上的握手...如何使用Coldfusion cfdirectory和randRange函数输出随机文件?

我需要创建一个直接的文件(说有10个文件),并输出5个随机文件。获取和输出文件是好的,但我不知道在哪里适合randrange。这里是我的代码:

<cfdirectory action="list" directory="#expandpath("img/")#" filter="some*.*" name="dir"> 
    <!--- imgID ---> 
    <CFSET imgID= #RandRange(1, #dir.allRecords#)#> 
    <!--- this only grabs the first 5 files ---> 
    <cfoutput query="dir" maxrows="5"> 
     <cfif FileExists("#expandpath("img/#name#")#")> 
     <cfimage source="#expandpath("img/#name#")#" name="myImage">             <cfif IsImage(myImage) is true> 
      <cfset ImageSetAntialiasing(myImage,"on")> 
       <cfset ImageScaleToFit(myImage,"highestQuality")> 
       <!--- append to a list ---> 
      <li><cfimage source="#myImage#" action="writeToBrowser"></li> 
      </cfif>    
     </cfif> 
     </cfoutput> 

这可以在显示前5个图像时正常工作。不过,我想要有5张的随机图片。

感谢您的一些见解!

编辑:
这是我最后只是 - 一个问题没有解决 -

<!-- get the directy, listinfo="name" because I only need filenames ---> 
<cfdirectory action="list" LISTINFO="name" directory="#expandpath(" logos/")#" filter="marke*.*" name="dir"> 

<cfset images=[ ]> 
<!-- since dir is not indexable, like dir[pos], I need another array!--> 
<cfset dirArr=[ ]> 
<cfset blocker="false"> 
<cfset maxLogos=5> 
<!-- fill new dirArr(ay) -->    
<cfoutput query="dir"> 
    <cfset #ArrayAppend(dirArr, #expandpath("logos/#name#")#)#> 
</cfoutput> 
<!-- loop --> 
<cfloop condition="blocker eq false"> 
    <-- random position --> 
    <cfset pos=R andRange(1, #dir.recordcount#)> 
    <cfif #dir.recordcount# eq 0 OR #ArrayLen(images)# gte #maxLogos#> 
     <-- STOP loop --> 
     <cfset blocker="true"> 
    </cfif> 
    <cfset ArrayAppend(images, #dirArr[pos]#)> 
    <!-- BROKEN unknown ARRAYDELETE --> 
    <!--- <cfset ArrayDelete(dirArr, #dirArr[pos]#)> ---> 
    <!-- IMG --> 
    <cfimage source="#dirArr[pos]#" name="myImage"> 
    <cfif IsImage(myImage) is true> 
     <cfoutput> 
     <li data-icon="false"> 
      <cfimage source="#myImage#" action="writeToBrowser"> 
     </li> 
     </cfoutput> 
    </cfif> 
</cfloop> 

问题是ArrayDelete不起作用变量ARRAYDELETE未定义,ColdFusion的(8)告诉我。任何想法我做错了什么?

+0

你想用'ArrayDeleteAt()'还引用您的ArrayDeleteAt变量时不需要输出迹象。 ''cfset ArrayDeleteAt(dirArr,dirArr [pos])>'除非您直接输出变量,否则几乎不需要使用#。 – 2012-04-23 11:54:32

+0

hm。那个错误:“值C:\ path \ logos \ marke1111111111114_test.png.png不能被转换为一个数字。” – frequent 2012-04-23 11:57:00

+1

关于代码风格的说明。只有当你需要围绕##中的变量或函数时,才打算输出结果。 是不必要的。 更具可读性。函数的参数也是如此myfunc(#varname#)是不好的做法,myfunc(varname)更可取 – 2012-04-23 12:03:19

回答

1

我不确定您的代码是否会实际工作,因为它似乎有几个语法错误。您还正在对IMG一个目录列表,但随后从标志拉的图像和你没有讲明是什么关系,这些目录之间预留

这些问题,这是我将如何处理这个。

<cfscript> 
// this code is untested, but should get you going 
// get list of image file names as an array 
dir = directoryList(expandPath("imgs"), false, "name", "*.jpg"); 
images = []; 
while(true) { 
    // if out directory list is now empty or we have 5 results, we're done 
    if(!arrayLen(dir) or arrayLen(images) gte 5) break; 
    // get an image from a random point in the list 
    pos = randrange(1, arrayLen(dir)); 
    // append it to our images array 
    arrayAppend(images, dir[pos]); 
    // delete form the source array, this avoids duplicates in further iterations 
    arrayDeleteAt(dir, pos); 
} 
</cfscript> 

这给出了一个图像数组,其中包含0到5个元素,然后可以将其输出为列表。

作为一个附注,不建议重复使用<cfimage>和相关函数。如果您需要调整大小或操作图像,则应将其缓存回磁盘,而不是每次请求重复操作。

+0

非常感谢,你说得对,我的错误现在清理了,然后按照你的建议进行尝试 – frequent 2012-04-23 09:19:49

+0

明白了,见上面我在ARRAYDELETE中还有一个问题是未定义的,不是我希望它是一个变量:-)任何想法? – frequent 2012-04-23 11:03:56

+0

什么是确切的错误信息? – 2012-04-23 11:53:35

3

一个简单的办法是一次洗牌的数组,然后取前五个项目:

<cfset MaxLogos = 5 /> 
<cfset Images = [] /> 
<cfset Files = DirectoryList(expandPath("logos") , false, "name" , "marke*.jpg") /> 

<cfset createObject("java", "java.util.Collections").shuffle(Files) /> 

<cfloop index="i" from="1" to=#Min(MaxLogos,ArrayLen(Files))# > 
    <cfset ArrayAppend(Images , Files[i]) /> 
</cfloop> 

<cfdump var=#Images# /> 
+0

我喜欢开箱即用的解决方案:-) – frequent 2012-04-23 18:13:02