Как сопоставить переменную в switch с содержимым списка? - PullRequest
2 голосов
/ 21 декабря 2011

У меня есть сомнения относительно использования переключателя в tcl. В основном мне было интересно, можно ли было сделать что-то вроде:

switch myvar {
    list1 {
        puts "myvar matches contents of list1"; }
    list2 {
        puts "myvar matches contents of list2"; }
    default {
        puts "myvar doesn't match any content of any list"; }
}

Здесь list1 и list2 будут либо списком, либо массивом строк, содержащих имена разных файлов.

Возможно ли это даже без очень подробного поиска регулярных выражений?

Спасибо!

Ответы [ 2 ]

6 голосов
/ 22 декабря 2011

Вы можете переписать его как конструкцию ififif else, как уже сказал Брайан Фентон (и упростить ее с помощью оператора 'in'.

if {$myvar in $list1} {
    puts "myvar matches content of list"
} elseif {$myvar in $list2} {
    puts "myvar matches content of list2"
} elseif {
    puts "myvar doesn't match any content of any list"
}

Конечно, вы можете свернуть код и написать свою собственную версию коммутатора, которая делает то, что вы хотите, в конце концов, это Tcl ...

proc listswitch {item conditions} {
     if {[llength $conditions] % 2} {
         return -code error "Conditions must be pairs"
     }
     set code ""
     foreach {cond block} $conditions {
        if {$cond eq "default"} { 
          set code $block
          break 
        } elseif {$item in $cond} {
          set code $block
          break
        }
     }
     if {$code ne ""} {
         uplevel 1 $code
     }
}


listswitch 10 {
   {10 20 30 50} {
       puts "Match in list 1" }
   {50 20 90 11} { 
       puts "Match in list 2"
    }
    default {
       puts "No match"
    }
}

Вам нужно немного беспокоиться, если вы хотите буквально сопоставлять имена файлов или какое равенство вас интересует. Там есть некоторые тонкие вещи, такие как нечувствительные к регистру файловые системы, различные разделители каталогов, абсолютные и относительные и даже такие вещи, как кодировки файловой системы, которые могут изменить результат.

1 голос
/ 21 декабря 2011

Хороший вопрос Джейсон.Сначала я подумал, что вам нужен способ сравнить содержимое двух списков.Но я думаю, что вы хотите проверить, является ли строка членом списков.Я не вижу простого способа сделать это с помощью switch , поэтому я бы очень просто использовал lsearch .

if {[lsearch $list1 $myvar ] != -1} {
  puts "myvar matches contents of list1"; }
} elseif {[lsearch $list2 $myvar ] != -1} {
  puts "myvar matches contents of list2"; }
} else
  puts "myvar doesn't match any content of any list"; }
}
...