Reputation: 11
So, lets say I have these two lists as below:
ListA
contains:
{{feed_sesmmu1_qmusharemem_se_smmu0_int}
{feed_sesmmu1_qmusharemem_se_smmu0_soc_rd_datvld}
{feed_sesmmu1_qmusharemem_se_smmu0_soc_rd_dat[31]}
{feed_sesmmu1_qmusharemem_se_smmu0_soc_rd_dat[30]}
{feed_sesmmu1_qmusharemem_se_smmu0_soc_rd_dat[29]}
{feed_sesmmu1_qmusharemem_se_smmu0_soc_rd_dat[28]}
{feed_sesmmu1_qmusharemem_se_smmu0_soc_rd_dat[27]}
{feed_sesmmu1_qmusharemem_se_smmu0_soc_rd_dat[26]}}
and ListB
:
{{se_smmu0_int}
{se_smmu0_soc_rd_datvld}
{se_smmu0_soc_rd_dat[29]}
{se_smmu0_soc_rd_dat[31]}
{se_smmu0_soc_rd_dat[30]}
{se_smmu0_soc_rd_dat[28]}
{se_smmu0_soc_rd_dat[26]}
{se_smmu0_soc_rd_dat[27]}}
Now I need {feed_sesmmu1_qmusharemem_se_smmu0_soc_rd_dat[27]}
to match {se_smmu0_soc_rd_dat[27]}
and other elements of listA
should match their counterparts in listB
.
Upvotes: 1
Views: 676
Reputation: 13252
You can do it with
lmap s $ListB {
lsearch -inline $listA *[string map {[ \\[ ] \\]} $s]
}
The idea is to take each item in the list ListB
and search for that item in the list listA
. There are to caveats: some of the items in ListB
have brackets ([
]
) in them, and those characters are special to the glob search that lsearch
uses by default. So we will escape them: string map {[ \\[ ] \\]} $s
. Also, the item from ListB
is going to be a suffix in listA
, so we need to prepend a star, *
for "any character".
If you don't have lmap
and don't want to use the drop-in replacement in the lmap (for Tcl 8.5) link:
set result {}
foreach s $ListB {
lappend result [lsearch -inline $listA *[string map {[ \\[ ] \\]} $s]]
}
puts $result
Documentation: foreach, lappend, lmap (for Tcl 8.5), lmap, lsearch, puts, set, string
Syntax of Tcl string matching:
*
matches a sequence of zero or more characters?
matches a single character[chars]
matches a single character in the set given by chars (^ does not negate; a range can be given as a-z)\x
matches the character x, even if that character is special (one of *?[]\
)Upvotes: 1
Reputation: 1947
Here's a solution with explicit foreach
loops, in case lmap
is not available. It also avoids glob-style string matching if favor of a range-based match:
proc endsWidth {s suffix} {
set index end-[expr {[string length $suffix]-1}]
return [expr {[string range $s $index end] eq $suffix}]
}
foreach b $listB {
foreach a $listA {
if {[endsWidth $a $b]} {
puts "$a $b"
}
}
}
Upvotes: 0