2009-07-11 09:10:05

Listの謎

テーマ:ColdFusionメモ
リストとは、区切り文字で区切られた複数のエントリで構成される文字列です。
よく使われるのはカンマ(,)区切りです。

<cfset data = "1,2,3,4,5">

カンマ区切りのリストの要素数は5つです。
では、以下の要素数はいくつでしょうか?

<cfset data = ",2,3,,">

ColdFusionでは2つとなります。(なんでーーー?)


会社ではCSVデータの取込処理を作ったりします。
その場合は、5つと認識して欲しいです。
カラムごとにデータの意味があるからです。

個人的に考えたのは、「NULL」という文字列を挿入してから処理する方法です。
または、「|」(縦棒?)を挿入します。
ありえない文字(列)を挿入します。


【変換前】
<cfset data = ",2,3,,">


【変換方法】
<cfif left(data,1) eq ",">
<cfset data = "NULL" & data>
</cfif>
<cfloop condition = "Find(',,',data) neq 0">
<cfset data = Replace(data, ",,",",NULL,","ALL")>
</cfloop>
<cfif right(data,1) eq ",">
<cfset data = data & "NULL">
</cfif>


【変換後】
<cfset data = "NULL,2,3,NULL,NULL">


4番目のデータはNULLなので、返す値はなにもありません。


上記のように、変換する関数と、指定カラムのデータを取り出す関数を作ると便利です。
実際に関数を作った場合の使用例

【データ変換】
<cfset data = csv2cflist(data,",","NULL")>

【4番目のデータを取得】
<cfset tmp = ListGetAtEx(data, 4, ",", "NULL")>

上記2つの関数は、「カンマ区切りで、NULL文字を挿入」という意味のパラメータを指定しています。
これが食い違うとどちらかがおかしくなります。

同じようなパラメータを持つ関数が多くなると、ちょっと面倒になります。
そうなるとコンポーネントという考え方が便利です。
オブジェクト指向として考えるわけです。


例:データを変換し、元データ、変換データ、変換データの要素を表示
<cfset obj = createObject("component", "csv2cflist").init(",","NULL")>
<cfset data = ",2,3,,">
<cfset obj.conv(data)>

<cfoutput>
moto = #obj.getMotoData()#<br>
conv = #obj.getConvData()#<br>
<br>
<cfloop index="idx" from="1" to="5">
#idx#=#obj.ListGetAtEx(idx)#<br>
</cfloop>
</cfoutput>


以下がコンポーネントのソースです。
【csv2cflist.cfc】
01: <cfcomponent>
02: 
03:     <!--- 区切り --->
04:     <cfset variables.sep = "">
05: 
06:     <!--- ヌルの時の変換文字列 --->
07:     <cfset variables.chgStr = "">
08: 
09:     <!--- 元データ --->
10:     <cfset variables.motoData = "">
11: 
12:     <!--- 変換後データ --->
13:     <cfset variables.convData = "">
14: 
15:     <!--- init --->
16:     <cffunction name="init"
17:                 access="public"
18:                 type="csv2cflist"
19:                 output="no">
20: 
21:         <cfargument name="sep"
22:                     type="string"
23:                     required="yes">
24: 
25:         <cfargument name="chgStr"
26:                     type="string"
27:                     required="yes">
28: 
29:         <cfset variables.sep    = arguments.sep>
30:         <cfset variables.chgStr = arguments.chgStr>
31: 
32:         <cfreturn this>
33:     </cffunction>
34: 
35: 
36:     <!--- 変換 --->
37:     <cffunction name="conv"
38:                 access="public"
39:                 type="void"
40:                 output="no">
41: 
42:         <cfargument name="data"
43:                     type="string"
44:                     required="yes">
45: 
46:         <cfset variables.motoData = arguments.data>
47:         <cfset variables.convData = arguments.data>
48: 
49:         <cfif left(variables.convData,1) eq variables.sep>
50:             <cfset variables.convData = variables.chgStr &
51:                                         variables.convData>
52:         </cfif>
53: 
54:         <cfloop condition = 
55:             "Find('#variables.sep##variables.sep#',
56:                     variables.convData) neq 0">
57: 
58:             <cfset variables.convData =
59:                         Replace(variables.convData,
60:                             "#variables.sep##variables.sep#",
61:                             "#variables.sep##variables.chgStr##variables.sep#",
62:                             "ALL")>
63:         </cfloop>
64: 
65:         <cfif right(variables.convData,1) eq variables.sep>
66:             <cfset variables.convData =
67:                         variables.convData &
68:                         variables.chgStr>
69:         </cfif>
70:     </cffunction>
71: 
72: 
73:     <!--- 指定カラムのデータ取得 --->
74:     <cffunction name="ListGetAtEx"
75:                 access="public"
76:                 type="string"
77:                 output="no">
78: 
79:         <cfargument name="no"
80:                     type="numeric"
81:                     required="yes">
82: 
83:         <cfset var tmp = "">
84:         <cfset tmp = ListGetAt(variables.convData,
85:                                 arguments.no,
86:                                 variables.sep)>
87: 
88:         <cfif tmp eq variables.chgStr>
89:             <cfreturn "">
90:         </cfif>
91: 
92:         <cfreturn tmp>
93:     </cffunction>
94: 
95: 
96:     <!--- 元データ --->
97:     <cffunction name="getMotoData"
98:                 access="public"
99:                 type="string"
00:                 output="no">
01: 
02:         <cfreturn variables.motoData>
03:     </cffunction>
04: 
05: 
06:     <!--- 変換データ --->
07:     <cffunction name="getConvData"
08:                 access="public"
09:                 type="string"
10:                 output="no">
11: 
12:         <cfreturn variables.convData>
13:     </cffunction>
14: 
15: </cfcomponent>
16: 
AD
いいね!した人  |  コメント(0)  |  リブログ(0)

うたらぼさんの読者になろう

ブログの更新情報が受け取れて、アクセスが簡単になります

コメント

[コメントをする]

コメント投稿

AD

ブログをはじめる

たくさんの芸能人・有名人が
書いているAmebaブログを
無料で簡単にはじめることができます。

公式トップブロガーへ応募

多くの方にご紹介したいブログを
執筆する方を「公式トップブロガー」
として認定しております。

芸能人・有名人ブログを開設

Amebaブログでは、芸能人・有名人ブログを
ご希望される著名人の方/事務所様を
随時募集しております。