Jump to content
UBot Underground

Recommended Posts

I've seen this question popping up many times in the Forum:

 

"How do I remove certain items from my list?"

 

...so I thought I'd post a simple piece of code with comments to explain the process.

 

We will start by building a test list to work with in this example.

Beware though... the list would be normally scraped or loaded from a file in most cases...

 

add list to list(%lst_Initial_List, $list from text("first element,second element,third el,fourth element", ","), "Delete", "Global")

The List named "lst_Initial_List" is automatically created/initialized by simply naming it with the add list to list command.

The list from text allows the creation of list elements by using an initial text constant/variable containing the chosen separator text within it - in this case the chosen separator is the comma symbol.

 

Now we have built a list containing 4 separate items/lines; something like this:

(see in Debugger)

  • first element
  • second element
  • third el
  • fourth element

As you can see, the third element is not typical...

 

Assuming we want to remove it from the results, here is what to do and WHY...

 

We shall start by initializing the counter that would position the elements when looping through the whole list:

(remember that the first position in a list is not 1, BUT 0)

 

set(#var_CYC_CurrentListElementNO, 0, "Global")

 

Next, we shall calculate the MAX number of loops; as our list has 4 elements, the result will be 4.

 

set(#var_CYC_MaximumListElements, $list total(%lst_Initial_List), "Global")

 

:ph34r:

Something for you to consider here:

The list has 4 (four) elements, however numbered from 0 to 3 (0, 1, 2, 3) - so we have to loop the whole list (4 max loops) but to select elements from the list upto loop #3 (the last list position, equivalent to the 4th loop).

 

I hope this is clearer now, folks - usually it is the reason of many errors for people not paying enough attention to these subtleties...

 

We will start looping through the list while juggling the positioning counter as needed.

The following logic will repeat ANY number of times, as long as the counter is....

...still LESS THAN the maximum number of elements in the list - in other words...

as long as #var_CYC_CurrentListElementNO < 4

 

When starting the loop, we have the comparison 0<4 which is TRUE:

loop while($comparison(#var_CYC_CurrentListElementNO, "<", #var_CYC_MaximumListElements)) {
}

 

Now we shall add some code inside, to be performed on each loop.

 

We start by reading the current list element into a temporary text variable (#var_CRT_CurrentListElementText) for further processing:

 

set(#var_CRT_CurrentListElementText, $list item(%lst_Initial_List, #var_CYC_CurrentListElementNO), "Global")

 

Once we have the element extracted we need to compare it with something, to either keep or dump it, accordingly.

 

In our case, as we want to dump the elements that don't follow the same mask, we will look into the variable to see if it contains the text: element - within it... using a conditional IF command and the contains parameter/function:

 

if($contains(#var_CRT_CurrentListElementText, "element")) {
 then {
 }
 else {
 }
}

 

The IF command has to branches that would execute depending on the logical value returned by the comparison:

  • the THEN Logic if the comparison result is TRUE,
  • the ELSE Logic if the comparison result is FALSE.

During our first loop, the IF will execute its THEN branch, as the first list element will contain the text: element - so the contains parameter/function will return a TRUE value.

 

We need to add some logic to the THEN branch here, to move on to the next loop in the cycle, because we will do nothing else with the list element, as long as it matches our mask.

 

 then {
	 increment(#var_CYC_CurrentListElementNO)
 }

 

We shall simply increment the looping variable and the program will then jump out of the IF and read and execute the next command coming in line after that...

(in this case the LOOP WHILE ends, so it will return back to the loop's beginning).

 

Once returned, will read a new element from the list (the next one), situated on position #1 in the list, as now the variable #var_CYC_CurrentListElementNO = 1 already... and so forth...

 

HOWEVER, when the variable #var_CYC_CurrentListElementNO = 2 (the third element of our list will be now the text "third el" - which, obviously, will not contain the text element within it anymore...) so that the IF will now default to its ELSE branch, as the contains parameter/function will return a FALSE value.

 

We shall add some code logic to the ELSE branch of the IF command now...

 

What we need to do is, once we decided we found an undesirable element of the list,

to REMOVE it using the remove from list command:

 

 else {
	 remove from list(%lst_Initial_List, #var_CYC_CurrentListElementNO)
 }

 

It is not enough though, because we still need to do something with our counters.

 

At this moment, the positioning on the list is #var_CYC_CurrentListElementNO = 2 BUT since we have deleted the original third list element: "third el" - it actually currently points to the next one on the list: "fourth element" - which initially was the fourth element but it is now the third one.

 

:ph34r:

As a result we CANNOT INCREMENT the counter. We need to shorten the list total instead, to cut off an extra loop that is not needed anymore, since we eliminated an unwanted element.

 

	 set(#var_CYC_MaximumListElements, $subtract(#var_CYC_MaximumListElements, 1), "Global")

:ph34r:

^^^ THIS is a VERY IMPORTANT trick!

 

So actually, the ELSE branch of the IF command becomes now...

 

 else {
	 remove from list(%lst_Initial_List, #var_CYC_CurrentListElementNO)
	 set(#var_CYC_MaximumListElements, $subtract(#var_CYC_MaximumListElements, 1), "Global")
 }

 

Let's put together the complete code now, so that we have a functional program:

 

add list to list(%lst_Initial_List, $list from text("first element,second element,third el,fourth element", ","), "Delete", "Global")
set(#var_CYC_CurrentListElementNO, 0, "Global")
set(#var_CYC_MaximumListElements, $list total(%lst_Initial_List), "Global")
loop while($comparison(#var_CYC_CurrentListElementNO, "<", #var_CYC_MaximumListElements)) {
set(#var_CRT_CurrentListElementText, $list item(%lst_Initial_List, #var_CYC_CurrentListElementNO), "Global")
if($contains(#var_CRT_CurrentListElementText, "element")) {
 then {
	 increment(#var_CYC_CurrentListElementNO)
 }
 else {
	 remove from list(%lst_Initial_List, #var_CYC_CurrentListElementNO)
	 set(#var_CYC_MaximumListElements, $subtract(#var_CYC_MaximumListElements, 1), "Global")
 }
}
}

 

I tried to be very thorough with the explanation, to help especially the newbies :blink:

I'm sure the savvy coders would have already known or easily understood it with much less details B)

 

HTH...

  • Like 6
Link to post
Share on other sites
  • 4 weeks later...

seriously though... you should get a raise or something

 

Ha, Ha, HA.. seriously, why not?..

 

I would gladly accept, LOL

 

Anyway, I'm glad you liked it and hope it helped you on developing your programming skills.

 

Cheers!

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...