Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 比较两个列表并返回差异_List_Variables_Loops_Tcl - Fatal编程技术网

List 比较两个列表并返回差异

List 比较两个列表并返回差异,list,variables,loops,tcl,List,Variables,Loops,Tcl,我有两个列表,我匹配它们并打印任何差异。这两个列表是FPGA站内的电缆连接。我需要确保: $list1上的所有连接都存在于$list2上,如果不存在,则应将错误保存在另一个列表中 $list2上的所有连接都存在于$list1上,因此我没有得到任何“错误”连接 任何一个列表中不存在的连接都应保存到另一个变量中 列表的格式如下: {{A.B2} {B.B3}} 而list2美元的等价物可能是: {{B.B3} {A.B2}} ^即使交换了连接,它仍然有效!我将这两个变量都保存在循环中的不同变量

我有两个列表,我匹配它们并打印任何差异。这两个列表是FPGA站内的电缆连接。我需要确保:

  • $list1
    上的所有连接都存在于
    $list2
    上,如果不存在,则应将错误保存在另一个列表中

  • $list2
    上的所有连接都存在于
    $list1
    上,因此我没有得到任何“错误”连接

  • 任何一个列表中不存在的连接都应保存到另一个变量中

  • 列表的格式如下:

    {{A.B2} {B.B3}} 
    
    而list2美元的等价物可能是:

    {{B.B3} {A.B2}}
    
    ^即使交换了连接,它仍然有效!我将这两个变量都保存在循环中的不同变量上,以便执行此操作:

    if {
        $physical == "$project" && $physical2 == "$project2"
        || $physical == "$project2" && $physical2 == "$project"
    } then {
        lappend verified "$project ($project2) VERIFIED\n"
        #incr cablecounter
        set h 0
    } elseif {
        $physical == "$project" && $physical2 != "$project2"
        || $physical != "$project" && $physical2 == "project2"
        || $physical == "$project2" && $physical2 != "project"
        || $physical != "$project2" && $physical2 == "project"
    } then {
        lappend nonverified "$project to $project2 NOT connected. Please check $physical and $physical2\n"
    } else {
        set g [expr $g - 1]
        incr h
        #puts "\n [llength configuredConnections]"      
        if {
            $h > [llength $configuredConnections] && $project != "$physical" && $project2 != "$physical2"
            || $h > [llength $configuredConnections] && $project != "physical2" && $project2 != "$physical"
        } {
            lappend nonverified "$project to $project2 wrong connection found. Please remove.\n"
            set h 0; incr g
        }   
    }
    
    这给了我所有错误的连接等,但它不是告诉我
    $list1
    上的元素在
    $list2
    上不存在,而是将其存储到
    $nonverified
    上,并将其列为“错误连接”,而不是列为“未连接”

    我是TCL idk新手该怎么办

    编辑:
    $project
    $project2
    $list1
    中的两个元素,
    $physical$physical2
    $list2
    中的元素


    我正在使用Tcl 8.4
    ldiff
    命令可以帮助您(编辑:我用Tcl 8.4-workable(如果您使用下面的
    lmap
    替换)替换了Tcl 8.6实现):

    调用

    ldiff $list1 $list2
    
    ldiff [ldiff $list0 $list1] $list2
    
    提供
    list1
    中未出现在
    list2
    中的所有元素,反之亦然

    两个列表中都不存在的项应该位于名为(比如)list0的列表中,您可以通过调用找到它们

    ldiff $list1 $list2
    
    ldiff [ldiff $list0 $list1] $list2
    
    为Tcl 8.4用户提供的
    lmap
    快速、肮脏的替代品:

    proc lmap {varname listval body} {
        upvar 1 $varname var
        set temp [list]
        foreach var $listval {
            lappend temp [uplevel 1 $body]
        }
        set temp
    }
    
    它不允许多个varname-listval对,但是
    ldiff
    不需要

    这应该为Tcl 8.4上的完整
    lmap
    命令提供一个有效的替代品,除非在使用8.6时仍然存在未显示的问题:

    proc lmap args {
        set body [lindex $args end]
        set args [lrange $args 0 end-1]
        set n 0
        set pairs [list]
        foreach {varname listval} $args {
            upvar 1 $varname var$n
            lappend pairs var$n $listval
            incr n
        }
        set temp [list]
        eval foreach $pairs [list {
            lappend temp [uplevel 1 $body]
        }]
        set temp
    }
    

    在这种情况下,我仍然推荐第一个替换建议:很少会出错。

    此过程将返回交叉点和两个列表之间的差异。对于Tcl 8.4,可以这样称呼它

    foreach {intersection not_in_list2 not_in_list1} \
            [intersect3 $list1 $list2] \
            break
    
    if {[llength $not_in_list2] > 0} {
        puts "NOT All the connections on the list1 exist on list2"
        puts $not_in_list2
    }
    
    if {[llength $not_in_list1] > 0} {
        puts "NOT All the connections on the list2 exist on list1"
        puts $not_in_list1
    }
    
    (Tcl 8.5及以上版本,您会

    lassign [intersect3 $list1 $list2] intersection not_in_list2 not_in_list1
    
    )

    intersect3
    proc是:

    #
    # intersect3 - perform the intersecting of two lists, returning a list
    # containing three lists.  The first list is everything in the first
    # list that wasn't in the second, the second list contains the intersection
    # of the two lists, the third list contains everything in the second list
    # that wasn't in the first.
    #
    
    proc intersect3 {list1 list2} {
        array set la1 {}
        array set lai {}
        array set la2 {}
        foreach v $list1 {
            set la1($v) {}
        }
        foreach v $list2 {
            set la2($v) {}
        }
        foreach elem [concat $list1 $list2] {
            if {[info exists la1($elem)] && [info exists la2($elem)]} {
                unset la1($elem)
                unset la2($elem)
                set lai($elem) {}
            }
        }
        list [lsort [array names la1]] [lsort [array names lai]] \
             [lsort [array names la2]]
    }
    
    我相信我是几年前从TclX偷来的。您可以(应该?)使用:


    我使用的是Tcl 8.4,没有lmap@user3201970:你现在有了;)您可能希望使用parens
    ()
    对您的条件进行分组,以便更具可读性,并且您可以确定首先要评估的是什么。按照习惯用法,最好使用
    lassign
    ,然后引用
    foreach
    方法作为8.4及之前版本的解决方法。
    {c d e f g} {a b} {h i}