proc ListComp { List1 List2 } {
set DiffList {}
foreach Item $List1 {
if { [ lsearch -exact $List2 $Item ] == -1 } {
lappend DiffList $Item
}
}
foreach Item $List2 {
if { [ lsearch -exact $List1 $Item ] == -1 } {
if { [ lsearch -exact $DiffList $Item ] == -1 } {
lappend DiffList $Item
}
}
}
return $DiffList
}
set diff [Listcomp $list1 $list2]
puts diff
输入:
list1 {red, yellow, green, blue, orange}
list2 {red, green, blue, orange}
预期输出:yellow
接收的输出:
yellow green
green blue
blue orange
orange
搜索和匹配应该是任意一种方式。如果列表1的长度>list2,则应打印list1中的额外元素。如果list1<list2,list1中被省略的元素应该打印
虽然你的代码(除了打字错误(可以工作,但它可以做得更简单,比如
set diff [lmap n [concat $list1 $list2] {
# Skip the elements that are in both lists
if {$n in $list1 && $n in $list2} continue
set n
}]
另一种方法是使用数组(或dict(:
set list1 {red yellow green blue orange}
set list2 {red green blue orange}
if {[llength $list1] > [llength $list2]} {
set long $list1
set short $list2
} else {
set long $list2
set short $list1
}
foreach elem $long {
set diff($elem) 1
# or: dict set diff $elem 1
}
foreach elem $short {
unset -nocomplain diff($elem)
# or: dict unset diff $elem
}
set difference [array names diff]
# or: set difference [dict keys $diff]
通常,每个列表都可以有其他列表没有的元素。因此,最好的方法是同时计算两个结果列表,即一个列表中存在的元素在另一个中不存在,反之亦然。然后由你决定如何处理这些信息。
proc ComputeUniques {listA listB} {
set A {}
set B {}
foreach a $listA {
dict set A $a 0; # The 0 is just an arbitrary value
}
foreach b $listB {
dict set B $b 0
dict unset A $b
}
foreach a $listA {
dict unset B $a
}
return [list [dict keys $A] [dict keys $B]]
}
注意,如果键不存在,dict unset
什么也不做,这是方便的,并且结果按照输入键的出现顺序(在输入列表设置不一样的情况下,严格按照第一次出现的顺序(。