Finding duplicate entries in a list
by Niv (KP) » Fri, 05 Sep 2008 15:52:20 GMT
I want to find all the duplicate entries in a list and write thm out.
So far I've done:
puts $f1 [lsort $mylist]
puts $f2 [lsort -unique $mylist]
and then compared them in Textpad. this was quick & easy, but surely
there's a way to do
what I want very simply and just write out the duplicat entries.
(This was to find any duplicate pin assignments in a large FPGA, which
there shouldn't be, I found 4!).
Regards, Kev P.
Re: Finding duplicate entries in a list
by Harm Olthof » Fri, 05 Sep 2008 16:29:30 GMT
maybe:
set l [list a a b c c]
foreach i $l {if {[info exists a($i)]} {puts $i} {set a($i) 1}}
a
c
The thing I don't like about this is that you build up an array. You will
to unset it afterwards.
Harm
Re: Finding duplicate entries in a list
by Andreas Kupries » Fri, 05 Sep 2008 17:03:41 GMT
"Niv (KP)" < XXXX@XXXXX.COM > writes:
proc getdups {list} {
array set tmp {}
# Count items in tmp
foreach item $list {
lappend tmp($item) .
}
# Drop all items with count 1, they are unique
foreach item [array names tmp] {
if {[llength $tmp($item)] > 1} continue
unset tmp($item)
}
# Return the remainder.
return [array names tmp]
}
--
So long,
Andreas Kupries < XXXX@XXXXX.COM >
< http://www.**--****.com/ ;
Developer @ < http://www.**--****.com/ ;
-------------------------------------------------------------------------------
Re: Finding duplicate entries in a list
by suchenwi » Fri, 05 Sep 2008 17:41:14 GMT
Best put this functionality in a proc, where the local array is
cleared up on exit.
Re: Finding duplicate entries in a list
by schlenk » Fri, 05 Sep 2008 18:24:02 GMT
If you have tcllib you can also use struct::set for this.
Michael
Re: Finding duplicate entries in a list
by Ron Fox » Fri, 05 Sep 2008 20:53:29 GMT
Would be simpler just to incr tmp($item)
then if ($tmp($item) > 1} continue
At least that's how us histogramming mind-set folks think
--
Ron Fox
NSCL
Michigan State University
East Lansing, MI 48824-1321
Re: Finding duplicate entries in a list
by Neil Madden » Fri, 05 Sep 2008 23:05:57 GMT
Another alternative to using an array is to sort the list and then
traverse once checking for duplicates -- all dups are grouped in the
sorted list, so detecting them is easy:
proc dups xs {
set dups [list]
set xs [lsort $xs]
set len [expr {[llength $xs]-1}]
for {set i 0} {$i < $len} {} {
set x [lindex $xs $i]
if {$x == [lindex $xs [incr i]]} {
lappend dups $x
# discard multiple repeats
while {[lindex $xs $i] == $x} { incr i }
}
}
return $dups
}
There doesn't seem to be any noticeable time difference between this and
the array version, however.
-- Neil
Re: Finding duplicate entries in a list
by Andreas Kupries » Wed, 10 Sep 2008 15:03:38 GMT
Ron Fox < XXXX@XXXXX.COM > writes:
Only in 8.5. In 8.4 you still need an [info exists/incr/set] dance,
the use of lappend and unary counting was easier.
--
So long,
Andreas Kupries < XXXX@XXXXX.COM >
< http://www.**--****.com/ ;
Developer @ < http://www.**--****.com/ ;
-------------------------------------------------------------------------------
Re: Finding duplicate entries in a list
by Sonya In Disguise » Fri, 12 Sep 2008 07:18:22 GMT
Another solution - this simply prints the duplicates:
proc prtDups { args } {
set argc [ llength $args ]
while { $argc > 1 } {
foreach item $args {
set group [ lsearch -all $args $item ]
set argc [ llength $group ]
if { $argc > 1 } {
puts "duplicate = [ lindex $args [ lindex $group 0 ] ]"
foreach i [ lsort -integer -decreasing $group ] {
set args [ lreplace $args $i $i ]
}
break;
}
}
}
}
set foo [ list a b b c c d e f ]
eval prtDups $foo
Sonya
Similar Threads:
1.Command to find unique entries in a list
Hi,
Whats the tcl command to get the unique entries in a list
Ex:
list:
green
blue
green
blue
to get the unique entries -- green, blue
We have uniq in Unix, The equivalent for uniq in TCL?
Please let me know
Thanks
2.Can any body tell me how to find duplicate lines in C
Can any body tell me how to find duplicate lines in C
i have tried to find using Binary tree and Text files but not suceeded
.
It works for Word but not for lines
please help me
you can write suggetion to my email : XXXX@XXXXX.COM
3.Duplicate elements in list
We have a list of elements, some are duplicates. We're trying to figure
out how to find the duplicate elements and increase a counter value by 1
for each instance of the element found. The list consists of lists with
two elements, the first being the incremental counter, the second being
the string sought. Example:
((1 "one") (1 "two") (1 "three") (1 "one") (1 "four") (1 "two"))
The result should be:
((2 "one") (2 "two") (1 "three") (1 "four"))
This is the function for adding 1 (incremental counter element):
(defun add-one-to-n (indata)
(setq n (car indata))
(setq outdata
(cons (+ 1 n) (cdr indata))))
Any ideas on how we should go about achieving this?
Nick and Jake
4.duplicates in lambda-list, let bindings, etc.
I stumbled across this interesting discrepancy between implementations:
CLisp:
(let ((x 1) (x 2))
x)
==> 2
ECL:
(let ((x 1) (x 2))
x)
==> 1
SBCL:
(let ((x 1) (x 1))
x)
...
; caught ERROR:
; The variable X occurs more than once in the lambda list.
...
It is similar but different for actual lambda lists:
CLisp+ECL:
(funcall (lambda (x x) x) 1 2)
==> 2
SBCL again brings the above error.
Is this unspecified by the standard? SBCL's behaviour seems to make most
sense to me, in terms of catching errors but maybe there's a reason why
there should not be an error.
5.Duplicate elements in list (solved)
Svein Ove Aas wrote:
> Niklas Brunberg wrote:
>
>
>>We have a list of elements, some are duplicates. We're trying to figure
>>out how to find the duplicate elements and increase a counter value by 1
>>for each instance of the element found. The list consists of lists with
>>two elements, the first being the incremental counter, the second being
>>the string sought. Example:
>>
>>((1 "one") (1 "two") (1 "three") (1 "one") (1 "four") (1 "two"))
>>
>>The result should be:
>>
>>((2 "one") (2 "two") (1 "three") (1 "four"))
>>
>>
>>This is the function for adding 1 (incremental counter element):
>>
>>(defun add-one-to-n (indata)
>> (setq n (car indata))
>> (setq outdata
>> (cons (+ 1 n) (cdr indata))))
>>
>>Any ideas on how we should go about achieving this?
>
>
> I'd use a hash table, much like this:
>
> (defun count (list)
> (let ((hash (make-hash-table)))
> (dolist (el list)
> (incf (gethash (cadr el) hash 0) (car el)))
> (let (result)
> (maphash (lambda (key val)
> (push (list val key) result))
> hash)
> result)))
>
Thank you Svein Ove Aas! Solved most of our problems!
/ Niklas and Jakob
6. duplicates in lambda lists
7. "entry point not found" error
8. Entry point not found error