Coldfusion breaking an array into two
Asked Answered
S

3

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>
Smoothspoken answered 5/6, 2013 at 19:47 Comment(0)
N
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,':')) >
Nativeborn answered 5/6, 2013 at 19:58 Comment(8)
Not quite, I am looking for the first element, both before and after the ":", not the first / last elementSmoothspoken
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.Monogamous
@JimRilye - getToken(value, position, ":") would probably do it. But please update your question to include a sample of the string, and desired result.Monogamous
@Leigh, edited question upon request. I'm trying something of the sort: <cfset selectList1 = listAppend(selectList1, GetToken(listFirst(i),0,":"))>Smoothspoken
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.Nativeborn
@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).Monogamous
CF typically does begin iterations with 0 No, most things are 1-based.Monogamous
Yep, I meant does not begin with 0.Nativeborn
P
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>
Population answered 6/6, 2013 at 10:55 Comment(0)
P
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

Positively answered 5/1, 2017 at 11:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.