Использование `lmap` для фильтрации списка строк

Предположим, я хочу получить все 5-буквенные слова из списка.

set words {apple banana grape pear peach}
lmap word $words {if {[string length $word] == 5} {expr {"$word"}} else continue}
# ==> apple grape peach

Я не доволен цитированием беспорядка expr {"$word"}, Я надеялся, что это сработает:

lmap word $words {if {[string length $word] == 5} {return $word} else continue}
# ==> apple

Какой элегантный способ "вернуть" строку из тела lmap?

2 ответа

Решение

Основным выбором является использование set или использовать string cat (при условии, что вы в курсе). Я разбил примеры ниже на несколько строк для ясности:

lmap word $words {
    if {[string length $word] != 5} {
        continue
    };
    set word
}
lmap word $words {
    if {[string length $word] == 5} {
        # Requires 8.6.3 or later
        string cat $word
    } else {
        continue
    }
}

Я обычно использую set:

lmap word $words {if {[string length $word] == 5} {set word} else continue}

или иногда (если я уверен expr не будет интерпретировать значение в word):

lmap word $words {expr {[string length $word] == 5 ? $word : [continue]}}

Там тоже это, конечно:

lsearch -regexp -all -inline $words ^.{5}$

Документация: продолжить, expr, if, lmap, lsearch, set, string

Другие вопросы по тегам