Delete an item in a comma separated list

JulieT

New Member
I'm trying to delete an item in a comma separated list. The delete method seems not to work unless the variable is in a frame.

For example: clist = "1,2,3,4,5".

I need it to be "1,3,4,5" if certain conditions are true.

Currently it is done by traversing the list with a do i = 1 to num-entries(clist) and rebuilding the list - this seems excessive.

I can use replace but have to make sure I take out extra commas also.

Is there an easier way?

Thanks,
JulieT
 

cgdev

New Member
Hi,

As far as my knowledge there are no methods to delete entries from a comma separated list.

I think you are talking about the delete method on widgets like combo-box, selection-list etc.

I think replace might be an easy way to delete the entry from a comma separated list if you know the position of the item you wanted to delete.

Position can be retrieved using the LOOKUP function.

I just wrote a simple code based on your example.

Code:
define variable xyz as char init "1,2,3,4,5" no-undo.   

xyz = replace(xyz,(entry(2,xyz) + ","),"").    
display xyz.

I hope this might help you..
 

bendaluz2

Member
That wont work if the entry you want to replace is last in the list

here is a generalised function

Code:
FUNCTION RemoveItemFromList RETURNS CHARACTER
    (pc-list AS CHARACTER,
     pc-removeitem AS CHARACTER,
     pc-delimiter AS CHARACTER):

    DEFINE VARIABLE li-pos AS INTEGER NO-UNDO.

    li-pos = LOOKUP(pc-removeitem,pc-list,pc-delimiter).

    IF li-pos > 0 THEN
    DO:
        ASSIGN ENTRY(li-pos,pc-list,pc-delimiter) = "".
        IF li-pos = 1 THEN
            pc-list = SUBSTRING(pc-list,2).
        ELSE IF li-pos = NUM-ENTRIES(pc-list,pc-delimiter) THEN
            pc-list = SUBSTRING(pc-list,1,length(pc-list) - 1).
        ELSE
            pc-list = REPLACE(pc-list,pc-delimiter + pc-delimiter,pc-delimiter).
    END.
    RETURN pc-list.

END FUNCTION.

DISP RemoveItemFromList("1,2,3,4,5","2",",") FORMAT "X(10)".
DISP RemoveItemFromList("1,2,3,4,5","1",",") FORMAT "X(10)".
DISP RemoveItemFromList("1,2,3,4,5","5",",") FORMAT "X(10)".
DISP RemoveItemFromList("1,2,3,4,5","6",",") FORMAT "X(10)".
 

Bruno

New Member
I prefer (IMHO) cgdev's solution, you can fix the problem with the last item as described below:

assign
xyz = replace(xyz,entry(<what ever entry in list>,xyz),'':U) /* remove entry */
xyz = replace(xyz,',,':U,',':U) /* remove doubled commas */
xyz = trim(xyz,',':U) /* remove heading/trailing comma */
.

or quick and dirty

assign
xyz = trim(replace(replace(xyz,entry(<what ever entry in list>,xyz),'':U),',,':U,',':U),',':U)
.
 

bendaluz2

Member
Ok, my implementation is a little more cumbersome, but imagine a list like

"Customer,CustomerID,CustomerName,CustomerNotes"

Try removing Customer from that list with your method ;)

Now, imagine JulieT's example extended a bit

"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25"

Using your method to remove the 2nd entry would result in

"1,3,4,5,6,7,8,9,10,11,1,13,14,15,16,17,18,19,0,1,3,4,5"

This is extremely dangerous as no Progress error is likely to occur - all the values are still valid integers. However, it is likely to lead to data corruption :runtear:
 

Bruno

New Member
You got me. I thought JulieT's list is as simple as shown in her initial question and she knows the position of the entry in the list.

Otherwise, your more generic function is well worth the overhead of a function call (not to mention how cumbersome my single-line statement is to maintain).
 

John Nebi

Member
Without reviewing Bruno's offering I came up with a hybrid that eliminates some of the IF stuff:

Code:
FUNCTION RemoveItemFromList RETURNS CHARACTER
	(pc-list AS CHARACTER,
	 pc-removeitem AS CHARACTER,
	 pc-delimiter AS CHARACTER):
	DEFINE VARIABLE li-pos AS INTEGER NO-UNDO.
	li-pos = LOOKUP(pc-removeitem,pc-list,pc-delimiter).
	IF li-pos > 0 THEN
	DO:
		ASSIGN ENTRY(li-pos,pc-list,pc-delimiter) = "".
		pc-list = TRIM(REPLACE(pc-list,pc-delimiter + pc-delimiter,pc-delimiter),pc-delimiter).
	END.
	RETURN pc-list.
END FUNCTION. 
DISP RemoveItemFromList("1,2,3,4,5","2",",") FORMAT "X(10)".
DISP RemoveItemFromList("1,2,3,4,5","1",",") FORMAT "X(10)".
DISP RemoveItemFromList("1,2,3,4,5","5",",") FORMAT "X(10)".
DISP RemoveItemFromList("1,2,3,4,5","6",",") FORMAT "X(10)".
 

EdInTheUK

New Member
John's solution does not preserve deliberate existing blank spaces in the list. Wondering if anyone's found a better method in the past 7 years?
 
def var cFind as char no-undo.
cFind = "," + itemtoremove + ",".
cList = "," + cList + ",".
cList = trim(replace(cList, cFind, ","), ",").

or simply:

cList = trim(replace( ( "," + cList + "," ), ( "," + cItem + "," ), ","), ",").

Enjoy :D
 
Top