比较 tcl 中的两个列表并获得列表之间的唯一差异列表
compare two lists in tcl and obtain list of only differences between lists
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
搜索和匹配应该是任意一种方式。如果 list1 > 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
}]
另一种方法是使用数组(或字典):
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
键不存在时什么都不做,方便,结果按输入键出现的顺序(严格按照第一次出现的顺序,如果是不是集合的输入列表)。
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
搜索和匹配应该是任意一种方式。如果 list1 > 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
}]
另一种方法是使用数组(或字典):
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
键不存在时什么都不做,方便,结果按输入键出现的顺序(严格按照第一次出现的顺序,如果是不是集合的输入列表)。