Collections and enumerators

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Collections and enumerators

Steve Dekorte-4
Here's a handy Smalltalk-like Collection object and a NeXT-like 
enumerator object. Let me know if anyone likes this stuff - I'm 
considering putting up some web pages with more Lua objects.

Steve

---------------



Collection = 
{
    clone = clone,
    elements = {},
    count = 0
}

function Collection:empty()
    self.elements = {}
end

function Collection:size()
    return self.count 
end

function Collection:add_(anObject)
    self.elements[self.count] = anObject
    self.count = self.count + 1
    return anObject
end

function Collection:insert_at_(anObject, anIndex)
    local index = self.count
    while ( index > anIndex  ) do
         self.elements[index] = self.elements[index-1]
	index = index - 1
    end
    self.elements[anIndex] = anObject
    self.count = self.count + 1
    return anObject
end

function Collection:removeObjectAt_(anIndex)
    local index = anIndex
    local anObject = self:at_(index)
    self.elements[index] = nil
    while ( index < self.count - 1 ) do
         self.elements[index] = self.elements[index + 1]
	index = index + 1
    end
    self.elements[self.count - 1] = nil
    self.count = self.count - 1
    return anObject
end

function Collection:remove_(anObject)
    local index = self:indexOf_(anObject)
    return self:removeObjectAt_(index)
end

function Collection:addAll_(aCollection)
    local enm = aCollection:enumerator()
    local item = enm:next()
    while ( item ~= nil ) do
	self.add_(item)
	item = enm:next()
    end
    return self
end

function Collection:indexOf_(anObject)
   local i, v = next(self.elements, nil)
   while i do
        if ( v == anObject ) then return i end
        i, v = next(self.elements, i)
    end
    return -1
end

function Collection:at_(index)
     return rawgettable( self.elements, index)
end

function Collection:at_put_(index, anObject)
    local oldObject = self.elements[index] 
    self.elements[index] = anObject
    return oldObject
end

function Collection:contains_(anItem)
   if ( self:indexOf_(anItem) == -1 ) then return 0 end
   return 1
end

function Collection:isEmpty_(anObject)
    if ( self.count == 0 ) then return 1 end
    return 0
end

function Collection:isNotEmpty_(anObject)
    if ( self.count == 0 ) then return 0 end
    return 1
end

function Collection:enumerator()
    local enm =  CollectionEnumerator:clone()
    enm.collection = self
    return enm
end

function Collection:sortBy_(astring) -- unfinished
    local enm =  self:enumerator()
    local c = 1
    local value = enm:next()
    while ( c < count ) do
        local e1 = self.elements[c]
        local d = c + 1
        while ( d < count ) do
            --local e2 = 
           d = d + 1
        end
        c = c + 1
    end
    return enm
end

function Collection:do_(aFunction)
    local enm =  self:enumerator()
    local object = enm:next()
    while ( object ) do
        aFunction(object)
        object = enm:next()
    end
end

function Collection:select_(aFunction) 
    local enm =  self:enumerator()
    local object = enm:next()
    local results = Collection:clone()
    while ( object ) do
        if ( aFunction(object) == 1 ) then results:add_(object) end
        object = enm:next()
    end
    return results
end

function Collection:send_to_(aMessage, aTarget)
    local enm =  self:enumerator()
    local object = enm:next()
    while ( object ) do
        aTarget[aMessage](aTarget, object)
        object = enm:next()
    end
end

function Collection:makeAllPerform_(astring)
    local enm =  self:enumerator()
    local i, v = next(self.elements, nil)
    while ( i ) do
        v[astring](v)
        i, v = next(self.elements, i)
    end
    return 0
end



--- Some tests and examples ---

aCollection = Collection:clone()
aCollection:add_("a")
aCollection:add_("b")
aCollection:add_(123)

NSLog(aCollection:at_(0).."\n")
NSLog(aCollection:at_(1).."\n")
NSLog(aCollection:at_(2).."\n")
NSLog("\n")

--aCollection:removeObjectAt_(1)
aCollection:remove_("b")

NSLog(aCollection:at_(0).."\n")
NSLog(aCollection:at_(1).."\n")
NSLog(tostring(aCollection:at_(2)).."\n")
NSLog("\n")

aCollection:at_put_(1, "x")

NSLog(aCollection:at_(0).."\n")
NSLog(aCollection:at_(1).."\n")
NSLog(tostring(aCollection:at_(2)).."\n")
NSLog("\n")

aCollection:insert_at_("d", 0)

NSLog(aCollection:at_(0).."\n")
NSLog(aCollection:at_(1).."\n")
NSLog(tostring(aCollection:at_(2)).."\n")
NSLog(tostring(aCollection:at_(3)).."\n")
NSLog("\n")

testObj = 
{
    print_ = function (self, string) NSLog(string) end
}

aCollection = Collection:clone()
aCollection:empty()
aCollection:add_(testObj)
aCollection:do_(function (object) object:print_("hi") end)


----------------------

CollectionEnumerator = 
{
    clone = clone,
    collection = nil,
    index = 0
}

function CollectionEnumerator:next()
    if ( self.index > self.collection:size() ) then return nil end
    local result = self.collection:at_(self.index)
    self.index = self.index + 1
    return result
end

function CollectionEnumerator:collection_(aCollection)
    self.collection = aCollection
    self.index = 0
end

function CollectionEnumerator:reset()
    self.index = 0
end

Reply | Threaded
Open this post in threaded view
|

Re: Collections and enumerators

Freek Brysse
-----Original Message-----
From: Steve Dekorte <[hidden email]>
To: Multiple recipients of list <[hidden email]>
Date: Tuesday, November 24, 1998 9:37 AM
Subject: Collections and enumerators


>
>Here's a handy Smalltalk-like Collection object and a NeXT-like
>enumerator object. Let me know if anyone likes this stuff - I'm
>considering putting up some web pages with more Lua objects.

Yes, a WWW page would be nice.  Don't forget to register your page with the
lua-team. They keep a list of all lua related projects.


Freek

Reply | Threaded
Open this post in threaded view
|

Re: Collections and enumerators

Luiz Henrique de Figueiredo
In reply to this post by Steve Dekorte-4
>From: "Freek Brysse" <[hidden email]>
>
>From: Steve Dekorte <[hidden email]>
>
>>Here's a handy Smalltalk-like Collection object and a NeXT-like
>>enumerator object. Let me know if anyone likes this stuff - I'm
>>considering putting up some web pages with more Lua objects.
>
>Yes, a WWW page would be nice.  Don't forget to register your page with the
>lua-team. They keep a list of all lua related projects.

Right! See http://www.tecgraf.puc-rio.br/lua/uses.html

There's also a handy form to be filled at
	http://www.tecgraf.puc-rio.br/lua/uses-form.html

(These pages are mirrored [spelling?] at http://csg.uwaterloo.ca/~lhf/lua/)

We encourage contributions to this list of projects.  Thanks.
--lhf

Reply | Threaded
Open this post in threaded view
|

Re: Collections and enumerators

Steve Dekorte-4
[hidden email] wrote:
> Steve,
> 
> Looks like some nice code.  Couple of questions: shouldn't empty_ set 
> count to 0?  

Yup, that's a bug - thanks!

> why do you use xxx_ for method names?  It seems cluttered.  
> I can understand using something like that to indicate "private" methods.

I used "_" to indicate how arguments fit into the message name.
For example:

 collection:insert_at_(myObject, 1)

means:

 collection insert:myObject at:1
 
 (notice how it's clear what the arguments do)

If the message was just:

 collection:insertAt(myObject, 1)

It's not clear what the message means without documentation.
For example, it looks like it could mean that it will find "myObject"
in the collection and insert "1" at it's position.

The underscore also allows me to implement automatic getters and setters
for method calls, so everything can be a message.

Steve