Module:FunList/Iterators: Difference between revisions

Add SelectManyEnumerator
No edit summary
(Add SelectManyEnumerator)
Line 163: Line 163:
else
else
return WhereEnumerator.new(self.source, self.predicate)
return WhereEnumerator.new(self.source, self.predicate)
end
end
-- WHERE ENUMERATOR --
local SelectManyEnumerator = setmetatable({}, { __index = Enumerator })
SelectManyEnumerator.__index = SelectManyEnumerator
SelectManyEnumerator.__pairs = Enumerator_mt.__pairs
function SelectManyEnumerator.new(source, selector)
    local self = setmetatable(Enumerator.new(), SelectManyEnumerator)
    self.state = 0
    self.source = source
    self.selector = selector
    self.position = 0
    self.enumerator = nil -- Enumerator of the source Enumerable
    self.sourceEnumerator = nil  -- Enumerator of the nested Enumerable
    return self
end
function SelectManyEnumerator:moveNext()
    while true do
        -- Setup state
        if self.state == 0 then
            self.position = 0
            self.enumerator = self.source:getEnumerator()
            self.state = -3 -- signal to get (first) nested enumerator
        end
        -- Grab next value from nested enumerator
        if self.state == -4 then
            if self.sourceEnumerator:moveNext() then
                self.current = self.sourceEnumerator.current
                self.index = self.sourceEnumerator.index
                self.state = -4 -- signal to get next item
                return true
            else
                self.state = -3 -- signal to get next enumerator
            end
        end
-- Grab nest nested enumerator
        if self.state == -3 then
            if self.enumerator:moveNext() then
                local current = self.enumerator.current
                self.position = self.position + 1
                local sourceTable = self.selector(current, self.position)
                -- We need to turn the nested table into an enumerator
                self.sourceEnumerator = TableEnumerator.new(sourceTable):getEnumerator()
                self.state = -4 -- signal to get next item
            else
            -- enumerator doesn't have any more nested enumerators.
                return false
            end
        end
    end
end
function SelectManyEnumerator:getEnumerator()
if self.state == 0 then
return self
else
return SelectManyEnumerator.new(self.source, self.predicate)
end
end
end
end
Line 170: Line 234:
     TableEnumerator = TableEnumerator,
     TableEnumerator = TableEnumerator,
     SelectEnumerator = SelectEnumerator,
     SelectEnumerator = SelectEnumerator,
     WhereEnumerator = WhereEnumerator
     WhereEnumerator = WhereEnumerator,
    SelectManyEnumerator = SelectManyEnumerator
}
}
2,875

edits