Reputation: 173
I am trying to search whether the list elements are not equal to 0 and if they are not then return the pointer to individual element or elements and append it to a list.
for example
list1 has {a b c d e
}
I use some api command to extract values of these elements to a new list
set list2 ""
foreach element $list1 {
lappend list2 [api] # Api is a procedure that queries a,b,c etc of list1 and then stores the value in list2.
}
$> puts $list2
$> {0 0 4 0 1}
this list2 can haave any number of elements in the list and the order is not fixed, so i want to develop something that will work for anything. For example list2 can be {0 0 0} or {0 0 0 0 1 2 0} etc.
Now coming back to my original question from this list first of all using lsearch or ay other command i want to detect whether any elements is 0 or not. If it is not then append it to a new list.
set nonzero_list ""
# code below is wrong, I am trying to explain only what I a trying to achieve.
if {[lsearch $list2 0] != -1} {
lappend nonzero_list ["element which is not zero, in our case it is 2nd and 4th element"]
}
Finally my output should show as :
$> puts $nonzero_list
{c e} # Note: these are not actual individual elements of list2 but these are values of list1 to which they are associated to
Hope am able to understand the question correctly.
Thanks in advance.
/For Hai Vu : updated question below
Your proc "filterNonZero" works fine. My Goal is to append the values of these numbers from the output of this proc to the new list. So, in the example snippet that you provided list 2 will get {1 2 3 5} that is correct but I want a new list list3 that belongs to corresponding values of these elements. For Example :
set list0 {a b c d e f g i}
do some processing and obtain list2 (i know what to do you here, use my API) -->
puts $list2
{0 1 2 0 3 0 0 5 0}
then use your proc to obtain list 2 ->
set list2 [filterNonZero $list1]
puts $list2
{ 1 2 3 5 }
--> Now do some processing and get the final result list3 ( i dont know how to do this part) -->
{b c e h}
Upvotes: 1
Views: 612
Reputation: 40733
If I understand your question correctly, you want to take as input a list and return a list of all non-zero items. Here is one way to do it.
# Given list1 which contains any number of integers, we want to return a
# list of all items that is non-zero
set list1 {0 1 2 0 3 0 0 5 0}
set list2 {}
foreach item $list1 {
if {$item != 0} {
lappend list2 $item
}
}
# At this point, list2 contains all the non-zero items from list1
puts "List1: $list1"
puts "List2: $list2"
Output:
List1: 0 1 2 0 3 0 0 5 0
List2: 1 2 3 5
You can turn this into a proc
(a procedure):
proc filterNonZero {theList} {
set newList {}
foreach item $theList {
if {$item != 0} {
lappend newList $item
}
}
return $newList
}
set list1 {0 1 2 0 3 0 0 5 0}
set list2 [filterNonZero $list1]; # list2 = {1 2 3 5}
Another way is to use the struct::list
package to filter out what you want:
package require struct::list
set list1 {0 1 2 0 3 0 0 5 0}
set list2 [struct::list filterfor item $list1 {$item != 0}]
puts "\nList2: $list2"
Let me see if I understand the problem correctly:
list1 | a b c d e f g h i
list2 | 0 1 2 0 3 0 0 5 0
result | b c e h
If this is what you want, the solution is simple:
# These are the input
set list1 {a b c d e f g h i}
set list2 {0 1 2 0 3 0 0 5 0}
set result {}
foreach item $list1 selector $list2 {
if {$selector != 0} {
lappend result $item
}
}
puts "result = $result"
list1
is the original list; list2
is what you get from calling [API]
. result
the correspond item in list1
foreach
loop does that: it cycles through both lists at the same time.list2
, which saves some steps.Upvotes: 1
Reputation: 137587
The way to filter is to:
set filteredList {}
foreach item $inputList {
if {[api $item] != 0} {
lappend filteredList $item,$val
}
}
In Tcl 8.6, I'd write this (because continue
skips the collecting of the result of the body):
set filteredList [lmap item $inputList {
if {[api $item] == 0} continue
set item
}]
I am always assuming that you pass the item into the API as an argument. That's highly advised!
Upvotes: 4