比较tcl中的两个列表,并获得仅列表之间差异的列表

  • 本文关键字:列表 之间 两个 tcl 比较 tcl
  • 更新时间 :
  • 英文 :

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什么也不做,这是方便的,并且结果按照输入键的出现顺序(在输入列表设置不一样的情况下,严格按照第一次出现的顺序(。

最新更新