我正在尝试搜索列表元素是否不等于0,如果它们不是,则返回指向单个元素或元素的指针并将其附加到列表中。
例如
list1有{a b c d e
}
我使用一些api命令将这些元素的值提取到新列表
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}
这个list2可以包含列表中的任意数量的元素,并且订单不是固定的,所以我想开发一些适合任何事情的东西。例如,list2可以是{0 0 0}或{0 0 0 0 1 2 0}等。
现在回到我原来的问题,首先使用lsearch或者其他命令,我想检测是否有任何元素是0。如果不是,则将其附加到新列表。
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"]
}
最后我的输出应显示为:
$> 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
希望能够正确理解这个问题。
提前致谢。
/对于Hai Vu:下面更新的问题
你的proc“filterNonZero”工作正常。我的目标是将这些数字的值从此proc的输出附加到新列表。因此,在您提供的示例代码段中,列表2将获得正确的{1 2 3 5},但我想要一个属于这些元素的相应值的新列表list3。例如:
set list0 {a b c d e f g i}
做一些处理并获得list2(我知道你在这里做什么,使用我的API) - >
puts $list2
{0 1 2 0 3 0 0 5 0}
然后使用您的proc获取列表2 - >
set list2 [filterNonZero $list1]
puts $list2
{ 1 2 3 5 }
- >现在做一些处理并获得最终结果列表3(我不知道如何做这部分) - >
{b c e h}
答案 0 :(得分:4)
过滤方式是:
set filteredList {}
foreach item $inputList {
if {[api $item] != 0} {
lappend filteredList $item,$val
}
}
在Tcl 8.6中,我写了这个(因为continue
跳过了收集身体的结果):
set filteredList [lmap item $inputList {
if {[api $item] == 0} continue
set item
}]
我总是假设您将项目作为参数传递给API。这是高度建议!
答案 1 :(得分:1)
如果我正确理解您的问题,您希望将列表作为输入并返回所有非零项目的列表。这是一种方法。
# 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"
输出:
List1: 0 1 2 0 3 0 0 5 0
List2: 1 2 3 5
您可以将其转换为proc
(程序):
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}
另一种方法是使用struct::list
包来过滤掉你想要的东西:
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"
让我看看我是否正确理解了这个问题:
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
如果这是你想要的,解决方案很简单:
# 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
是原始列表; list2
是您通过致电[API]
获得的。 result
list1
对应的项目
foreach
循环执行此操作:它同时在两个列表中循环。list2
,这可以节省一些步骤。