5

Can I split an array into two separated ones with each element in the original array separated by a ":"? The text before the ":" goes to array1, the text after ":" goes to array2

<cfset tempArr = DeserializeJSON(URL.data) />
<cfset selectList = "" />
    <cfloop array=#tempArr# index="i">
<cfset selectList = listappend(selectList,i) />
</cfloop>

Right now this code grabs the whole element and not separately.

Edit

A sample string would be:

first_name:Bob


first_name goes into selectList1 Bob goes into selectList2


The grand scheme of things would have other fields likewise:

first_name:Bob

last_name:Shmo

age:27

etc...

EDIT: Answer

Problem was solved by using the code

<!---Variables--->
<cfset temp1 = "" />
<cfset temp2 = "" />
<cfset selectList1 = "" /><!---Holds column names for tables--->
<cfset selectList2 = "" /><!---Holds query parameters for column names. Ie,
                                    values for use in the WHERE clause--->

<cfloop array=#tempArr# index="i"><!---Loop through contents of the array--->
    <cfset temp1 = GetToken(i,1,":")/><!---Store the column name--->
    <cfset temp2 = GetToken(i,2,":")/><!---Query parameter--->

    <cfset selectList1 = listAppend(selectList1, temp1)/><!---Adds to list of column names--->
    <cfset selectList2 = listAppend(selectList2, temp2)/><!---Adds to the list of query parameters--->
</cfloop>
James A Mohler
  • 11,060
  • 15
  • 46
  • 72
reZach
  • 8,945
  • 12
  • 51
  • 97

3 Answers3

9

I think without seeing your array example, you mean splitting the data in the array into two lists?

<cfset selectList1 = listAppend(selectList1, listFirst(i,':')) >
<cfset selectList2 = listAppend(selectList2, listLast(i,':')) >
Leigh
  • 28,765
  • 10
  • 55
  • 103
williambq
  • 1,125
  • 7
  • 12
  • Not quite, I am looking for the first element, both before and after the ":", not the first / last element – reZach Jun 05 '13 at 20:05
  • 2
    FYI: Another option is using `getToken`. Its advantage over `listFirst/Last` is you do not need to validate the length. `getToken` returns an empty string if the given list element does not exist. In this case if it has less than two elements. – Leigh Jun 05 '13 at 20:05
  • 1
    @JimRilye - `getToken(value, position, ":")` would probably do it. But please [update your question](http://stackoverflow.com/q/16948546/104223) to include a sample of the string, and desired result. – Leigh Jun 05 '13 at 20:06
  • @Leigh, edited question upon request. I'm trying something of the sort: – reZach Jun 05 '13 at 20:11
  • Given update to question, if there are always two parts (Name:Bob), either listFirst/Last or getToken(i,1/2,':') should work for you. Remember CF typically does begin iterations with 0, and remember to quote strings (':'). The big advantage of getToken is when dealing with an unknown or varying set of elements separated by a given token or delimiter. – williambq Jun 05 '13 at 20:17
  • 1
    @JimRilye - Sorry I do not see the difference ;-) If the *individual* array elements `i`, always contain two strings separated by a single colon ie `foo:bar`, then williambq's original code should work fine. (Personally I prefer `getToken`, but technically both work). – Leigh Jun 05 '13 at 20:25
  • 4
    *CF typically does begin iterations with 0* No, most things are 1-based. – Leigh Jun 05 '13 at 20:29
  • Yep, I meant does *not* begin with 0. – williambq Jun 05 '13 at 22:57
1
<cfscript>   
variables.lstString             = "First_Name:John,Last_Name:McClane";
variables.lstFields             = "";
variables.lstValues             = "";

for(variables.i=1;variables.i lte listlen(variables.lstString,',');variables.i++){
    variables.lstFields         &= (listlen(variables.lstFields) gt 0) ? ",#getToken(getToken(variables.lstString,variables.i,','),1,':')#" : getToken(getToken(variables.lstString,variables.i,','),1,':');
    variables.lstValues         &= (listlen(variables.lstValues) gt 0) ? ",#getToken(getToken(variables.lstString,variables.i,','),2,':')#" : getToken(getToken(variables.lstString,variables.i,','),2,':');
}

writeDump(variables.lstFields);
writeDump(variables.lstValues);
</cfscript>
Jarede
  • 3,310
  • 4
  • 44
  • 68
0

why not convert the array in a list

<cfset list = arraytolist(array,",")>

and then use regex for getting the first chunk of elements, e.g. half the len of the array or whatever you like chunk size.

<cfset chunksize = int(listlen(list)/2)+1>

and then do a new array with a listpart (chunK) in each element:

<cfscript>
    function ListSplit(list, chunkysize, delim)
    {
        var result = ArrayNew(1); 
        var re = "";
        var start = 1;
        while(1) {
            re = REFind("((?:[^#delim#]+#delim#){1,#chunkysize#})", list & delim, start, "true");
            if( re.len[1] eq 0 ) break;
            ArrayAppend(result, Mid(list,re.pos[1],re.len[1]-len(delim)));
            start = re.pos[1] + re.len[1];
            if(start gte len(list)) break;
        }
        return result;
    }
</cfscript> 
<cfset newarray = ListSplit(list, chunksize, ",")>

e.g. list is 1,2,3,5,10,11,22,33,44,55,60,61,62,63,64 and you want split the list in 2 chunks then chunksize will be 8 the array will be result[1] = "1,2,3,5,10,11,22,33" result[2] = "44,55,60,61,62,63,64"

or get 3 chunks with gives you result[1] = "1,2,3,5,10" result[2] = "11,22,33,44,55" result[3] = "60,61,62,63,64"

etc.

I found the script from Nathan Youngman https://gist.github.com/nathany/742242 its very useful for dividing long lists or array in chunks of a given size

Raffael Meier
  • 189
  • 1
  • 4