【问题标题】:Remove duplicate elements from a tcl List从 tcl 列表中删除重复元素
【发布时间】:2021-07-01 12:18:19
【问题描述】:

我有一个列表变量 $a,它的值如下。

{1|Katy|347689    2|Jerry|467841  1|Katy|987654}

我正在尝试删除重复的基础上

1|Katy avoiding the userid available at last.

预期的输出应该是。

{1|Katy|347689 2|Jerry|467841}

我尝试使用 lsort -unique 选项。在我的情况下,这似乎无法正常工作。

set uniqueElement [lsort -unique $a]

此外,仅出于说明目的,列表值显示为具有 3 个值。我有500多个相同格式的。我试图在 1|Katy 的基础上删除重复项,同时避免使用用户 ID。 可以建议我可以解决此问题的任何其他方法以删除此格式的列表中的重复项吗?

【问题讨论】:

    标签: list tcl


    【解决方案1】:

    这有点棘手,因为您有在重复数据删除时要忽略的部分。因此,lsort -unique 不是正确的工具。相反,您想使用字典。

    # Identify the values that each key maps to
    set d {}
    foreach entry $inputList {
        # Alternatively, use regular expressions to do the entry parsing
        set value [join [lassign [split $entry "|"] a b] "|"]
        set key [string cat $a "|" $b]
    
        dict lappend d $key $value
    }
    
    # Build the output list using the first value each key maps to
    set outputList {}
    dict for {key values} $d {
        lappend outputList [string cat $key "|" [lindex $values 0]]
    }
    

    这使outputList 保持您正在寻找的价值。 (你不需要使用string cat,但我认为在这种情况下它会使代码更清晰。)

    【讨论】:

    • 我仅限于 8.5 版。 dict lappend 对我不起作用。
    【解决方案2】:

    您仍然可以通过预先操作您的初始列表来使用lsort -unique

        set new_format_list [join [split $a "|"] ]
        set new_format_sorted_list [lsort -unique -stride 3 $new_format_list]
        foreach {el1 el2 el3} $new_format_sorted_list  {
          lappend newlist "$el1|$el2|$el3"
        }
        puts "$newlist"
    
    1. 变量new_format_list 现在是条目列表中所有元素的平面列表(此处为9 个元素)。 | 已用于拆分初始列表的元素。
    2. 变量new_format_sorted_list 实际上删除了重复项。步幅 3 表示列表中的元素将逐个 3 进行检查。只有 3 个中的第一个用于比较。
    3. foreach 用于创建与条目中使用的格式相同的列表。 lappend 能够创建不存在的变量。
    4. 检查结果

    通常,你应该得到你想要的。

    根据 nurdglaw 相关评论进行编辑

    # entry list
    set original_list {1|Katy|347689    2|Jerry|467841  1|Katy|987654}
    
    set temp_list [join [split $original_list "|"] ]
    
    # dirty method
    # separate the third element from the first two 
    # then the string of the first two elements is the id for uniqueness
    foreach {l1 l2 l3} $temp_list {
        append new_format_list "$l1|$l2 $l3 " ;# use string to make a tcl list
        #the space at this end is mandatory
    } 
    set new_format_sorted_list [lsort -unique -stride 2 $new_format_list]
    
    foreach {el1 el2} $new_format_sorted_list  {
      lappend cleanlist "$el1|$el2"
    }
    puts "$cleanlist"
    

    【讨论】:

    • 虽然这个答案适用于 OP 的示例数据,但我不确定它是否能解决他最初提出的问题。如果输入数据是 {1|Katy|347689 1|Jerry|467841 1|Katy|987654} 怎么办?我认为您的代码将丢弃 1|Jerry467841 条目。很明显,在查找可能的重复项时,OP 只想忽略条目的第三部分 - 您的代码也忽略了第二部分。
    • 你是对的,我没有得到 OP 希望根据前 2 个值保留条目
    猜你喜欢
    • 2015-01-05
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多