Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Compare two lists and create two more with duplicates removed

Status
Not open for further replies.

Hoodyy

Technical User
Apr 13, 2016
3
GB
Hi all,

I'm just learning Tcl, so this is probably basic. Essentially, I have two lists of data that can be any length (however both lists will always be the same length).

What I'm trying to do is create a 3rd and 4th list with the duplicates removed. I should mention that the two lists are associated with each other, so I cannot lose the position.

For example, say I have the following two lists:

set list [list 10 10 5 4 5]
set list2 [list 2 2 3 2 2]

What I want the code to do is create two lists (or an array?) that have removed the duplicates, so the output would look like:

set newlist [list 10 5 4 5]
set newlist2 [list 2 3 2 2]

Thus it has removed one of the duplicate data set 10,2.

The code I have written to do this is as follows:
Code:
set list [list 10 10 5 4 5]
set list2 [list 2 2 3 2 2]
set newlist { }
set newlist2 { }

foreach i $list j $list2 {
	if { $i ni $newlist && $j ni $newlist2 } {
		lappend newlist $i
		lappend newlist2 $j
	} elseif { $i in $newlist && $j ni $newlist2 } {
		lappend newlist $i
		lappend newlist2 $j
	} elseif { $i ni $newlist && $j in $newlist2 } {
		lappend newlist  $i
		lappend newlist2 $j
	}
}
puts $newlist
puts $newlist2
This returns:
10 5 4
2 3 2

(thus missing the 5,2 data point). I think I've been going about this all the wrong way, so any help would be appreciated! (Also if you could explain the right code like I'm 5, that'd be great to help my learning of tcl!)

Thanks,
Matt
 
Hi

With [tt]in[/tt] and [tt]ni[/tt] you only find out whether the element is in the list or not, regardless its position.

The easiest is to have a temporary list where you keep the values as pairs so you can check the existence of pairs :
Code:
[b]set[/b] list [list 10 10 5 4 5]
[b]set[/b] list2 [list 2 2 3 2 2]

[b]set[/b] newlist { }
[b]set[/b] newlist2 { }

[highlight][b]set[/b] templist {}[/highlight]
[b]foreach[/b] i $list j $list2 {
    [b]if[/b] { [highlight][[b]list[/b] $i $j][/highlight] ni [highlight]$templist[/highlight] } {
        [b]lappend[/b] newlist $i
        [b]lappend[/b] newlist2 $j
        [highlight][b]lappend[/b] templist [[b]list[/b] $i $j][/highlight]
    }
}

[b]puts[/b] $newlist
[b]puts[/b] $newlist2

Feherke.
feherke.ga
 
Thanks Feherke,

This works perfectly.

I'm now struggling with the next step of this problem, which involves relating back the unique pairs to the original data.

For example, I have x amount of data (let's say 5 for an example). These 5 ID's will have two data points associated to them (in two lists as per the example above). I need the find the unique pairs from these data points in order to calculate something (in my case, create a PBUSH card in Hypermesh). Then after this I need to assign this need value back to the original ID. The trouble I'm having is that where my original lists have a length of 5, my new list (3rd new list) is a length of 4 and I can't figure out how to work back to assign the original IDs the property.

I'll try to lay out what I want to achieve below using the example above: (Let's assume the 3rd new list is created by adding the new lists together)

ID: 1, 2, 3, 4, 5
list: 10, 10, 5, 4, 5
list2: 2, 2, 3, 2, 2
newlist1: 10, 5, 4, 5
newlist2: 2, 3, 2, 2
newlist3: 12, 8, 6, 7

Assigning IDs to corresponding newlist3
ID 1, 2, 3, 4, 5
assign: 12, 12, 8, 6, 7

I tried to make the example simple, but in reality I could have 100+ ID's and data for list1 and list2 and may only need to make 3 property cards (3 unique pairs).

Thanks in advance for any insight
Matt
 
Hi

Matt said:
Then after this I need to assign this need value back to the original ID.
That sounds like scratching you right ear with your left hand ;-)

You have all the information inside the [tt]foreach[/tt] loop, so build all the lists you will need there :
Code:
[b]set[/b] idlist [[b]list[/b] 1 2 3 4 5]
[b]set[/b] list [[b]list[/b] 10 10 5 4 5]
[b]set[/b] list2 [[b]list[/b] 2 2 3 2 2]

[b]set[/b] newlist1 {}
[b]set[/b] newlist2 {}
[b]set[/b] newlist3 {}
[b]set[/b] assign {}

[b]set[/b] templist {}
[b]foreach[/b] i $list j $list2 {
    [b]if[/b] { [[b]list[/b] $i $j] ni $templist } {
        [b]lappend[/b] newlist1 $i
        [b]lappend[/b] newlist2 $j
        [b]lappend[/b] newlist3 [[b]expr[/b] $i + $j]
        [b]lappend[/b] templist [[b]list[/b] $i $j]
    }
    [b]lappend[/b] assign [[b]expr[/b] $i + $j]
}

[b]puts[/b] [i]"newlist1: $newlist1"[/i]
[b]puts[/b] [i]"newlist1: $newlist2"[/i]
[b]puts[/b] [i]"newlist1: $newlist3"[/i]

[b]puts[/b] [i]"ID:       $idlist"[/i]
[b]puts[/b] [i]"assign:   $assign"[/i]

Feherke.
feherke.ga
 
I think I need the assign set in your example to be created using the newlist3 set, because in my problem I am create an entity in a program and then taking the ID of that to put in a list. Therefore it's not as simple as using the [expr ] command.

Here's my code currently:
Code:
set x 0
set proplist {}
set ka_unique {}
set ks_unique {}
	
set templist {}
foreach i $ks j $ka {
	if { $x == 0} {
		set prop_name "PBUSH"
	}	else {
		set prop_name "PBUSH_$x"
	}
	if { [list $i $j] ni $templist } {
		#create unique pairs of ka and ks
		lappend ks_unique $i
		lappend ka_unique $j
		lappend templist [list $i $j]
		}
	#create pbush cards
	foreach a $ka_unique b $ks_unique {
		*collectorcreateonly property $prop_name "" [expr 1 + $x]
		*createmark prop 1 -1
		set templatedir [hm_info -appinfo SPECIFIEDPATH TEMPLATES_DIR];	
		set dict [file join $templatedir "feoutput" "nastran" "general"];
		*dictionaryload properties 1 $dict PBUSH
		*initializeattributes properties $prop_name
		set propID [hm_getmark properties 1]
		*attributeupdateint properties $propID 872 1 2 0 1
		*attributeupdatedouble properties $propID 845 1 1 0 $a
		*attributeupdatedouble properties $propID 846 1 1 0 $b
		*attributeupdatedouble properties $propID 847 1 1 0 $b
		*attributeupdatedouble properties $propID 848 1 1 0 100000
		*attributeupdatedouble properties $propID 849 1 1 0 100000
		*attributeupdatedouble properties $propID 850 1 1 0 0
		lappend proplist $prop_name
        }
	incr x
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top