smalltalk - check if 2 linked list have the same elements regardless of order -
is there way check if 2 linked lists have same elements regardless of order.
edit question: have fixed code , given more details:
this method compares 2 lists
compare: object2 ^ ((mylist asbag) = ((objetc2 getlist) asbag)).
the method belongs class myclass has field : myllist. mylist linkedlist of type element.
i have compiled in workspace:
a: = element new id:1. b:= element new id:2. c:=element new id:3. d: = element new id:1. e:= element new id:2. f:=element new id:3. elements1 := myclass new. elements addfirst:a. elements addfirst:b. elements addfirst:c. elements2 := myclass new. elements addfirst:d. elements addfirst:e. elements addfirst:f. transcript show: (elements1 compare:elements2).
so getting false.. seems checks equality reference rather equality value..
so think correct question ask be: how can compare 2 bags value? have tried '=='..but returned false.
edit: question changed too - think deserves new question itself.
the whole problem here (element new id: 1) = (element new id: 1)
giving false
. unless it's particular class (or superclasses) redefine it, =
message resolved comparing identity (==
) default. that's why code works collection being compared itself.
test with, example, lists of numbers (which have =
method redefined reflect humans understand numeric equality), , work.
you should redefine element
's class' =
(and hashcode
) methods work.
smalltalk handles everything reference: there exist object, know (reference) other objects.
it wrong 2 lists equivalent if in different order, order is part of list means. list without order call bag.
the asbag
message (as of other as<anothercollectiontype>
messages) return new collection of named type elements of receiver. so, #(1 2 3 2)
array
of 4 elements, , #(1 2 3 2) asbag
bag containing 4 elements. it's bag, doesn't have particular order.
when baga := bag new.
creating new bag
instance, , reference baga
variable. baga := mylist asbag
, lose reference previous bag - first assignment doesn't useful in code, don't use bag.
saying abool iftrue: [^true] iffalse: [^false]
has same meaning saying ^abool
- prefer that. and, create 2 new bags compare them, simplify whole method this:
compareto: anotherlist ^ mylist asbag = anotherlist asbag
read out loud: this object (whatever is) compares to list if it's list without considering order same other list without order.
the name compareto:
kind of weird returning boolean (containssameelements:
more descriptive), point much faster code.
just precise questions:
1) doesn't work because you're comparing bag1
, bag2
, defined baga
, bagb
.
2) it's not efficient create 2 bags because, , send senseless iftrue:
message, other way it's ok. may implement better way compare lists, it's way better rely on implementation of asbag
, bag
's =
message being performant.
3) think see asbag
source code, but, yes, can assume like:
collection>>asbag |instance| instance := bag new. instance addall: self. ^instance
and, of course, addall:
method be:
collection>>addall: anothercollection anothercollection do: [ :element | self add: element ]
so, yes - creates new bag receiver's elements.
Comments
Post a Comment