Page 1 of 1

FindListElement() and FindStructuredListElement()

Posted: Tue Jul 06, 2010 1:31 am
by Seymour Clufley
These would be useful IMHO.

Code: Select all

NewList fruit.s()
AddElement(fruit())
fruit() = "apple"

If FindListElement(fruit(),"apple",#PB_String)
Debug fruit() ; "apple" is now current element
EndIf
And the structured list version would work just like SortStructuredList():

Code: Select all

Structure fruitStructure
name.s
colour.i
EndStructure

NewList fruit.fruitStructure()

; code
; code
; code

If FindStructuredListElement(fruit(),OffsetOf(fruitStructure,name),"apple",#PB_String)
// if found, it's now the current element
Debug fruit()\name
EndIf
I know a list can contain two elements with identical content, so these functions would simply return the first element found.

Re: FindListElement() and FindStructuredListElement()

Posted: Tue Jul 06, 2010 2:31 am
by netmaestro
All lists would have to be indexed on all structure elements for this to be a reality. That's a lot of extra overhead that you'd only want occasionally. I don't believe the team has this vision for the linkedlist. The Map object has fast random-access, or perhaps an in-memory SQLite database could be alternatives.

Re: FindListElement() and FindStructuredListElement()

Posted: Tue Jul 06, 2010 11:02 am
by Seymour Clufley
All lists would have to be indexed on all structure elements for this to be a reality
Or the function could just loop through the list until it finds a matching element.

I've written a macro that does this. Of course, since it contains a loop it can't return a value, and I can't write it as a procedure because of different list types. That's why I'm suggesting this as a feature request.

Yes maps provide fast random access, and they're fantastic, but we use lists for other purposes and for them, a native FindListElement() function would be as useful as FindMapElement().

Re: FindListElement() and FindStructuredListElement()

Posted: Tue Jul 06, 2010 2:02 pm
by Jihugen
I would also greatly appreciate this feature (with type #PB_String_NoCase available, of course ;) ).

As Seymour said, we can't easily write our own generic function because we can't manage different types in PB procedure.
So we can write a dedicated procedure each time this feature is needed (that's what I did just last week when I realize that writing a generic FindListElement() procedure would be impossible), or we can also use Macro like Seymour did.
Of course, it's no big deal, but a native FindListElement() could be more efficient.
Seymour Clufley wrote:
All lists would have to be indexed on all structure elements for this to be a reality
Or the function could just loop through the list until it finds a matching element.
I'm no sure I get exactly what netmastro meant, but a loop could indeed be enough, as anyhow that's the way we have to proceed when we need such a function (and I'm quite sure that the native function could only be faster than our own loop).

Re: FindListElement() and FindStructuredListElement()

Posted: Tue Jul 06, 2010 3:13 pm
by freak
PB does not have polymorphic functions, so we can't do a function which can accept different types as a parameter.

Re: FindListElement() and FindStructuredListElement()

Posted: Sun Jul 11, 2010 6:01 pm
by Trond
Your templated FindElement is served:

Code: Select all

Macro UseFindElement(Type)
  Procedure FindElement#Type(List L.Type(), Needle.Type)
    ResetList(L())
    Repeat
      *Ptr = NextElement(L())
    Until *Ptr = 0 Or L() = Needle
    ProcedureReturn *Ptr
  EndProcedure
EndMacro

UseFindElement(S)

NewList fruit.s()
AddElement(fruit())
fruit() = "apple"
AddElement(fruit())
fruit() = "orange"
AddElement(fruit())
fruit() = "plum"

If FindElementS(fruit(), "orange")
  Debug fruit() ; "apple" is now current element
EndIf
And FindStructuredElement() (the generated procedures leave out "structured" from the name to avoid typing):

Code: Select all

Macro UseFindStructuredElement(Type, Field, FieldType, ID = )
  Procedure FindElement#Type#ID(List L.Type(), Needle.FieldType)
    ResetList(L())
    Repeat
      *Ptr = NextElement(L())
    Until *Ptr = 0 Or L()Field = Needle
    ProcedureReturn *Ptr
  EndProcedure
EndMacro

Structure fruitStructure
  name.s
  colour.i
EndStructure

UseFindStructuredElement(fruitStructure, \name, s)
UseFindStructuredElement(fruitStructure, \colour, i, ByColour)

NewList fruit.fruitStructure()
AddElement(fruit())
fruit()\name = "apple"
fruit()\colour = 1
AddElement(fruit())
fruit()\name = "plum"
fruit()\colour = 2
AddElement(fruit())
fruit()\name = "orange"
fruit()\colour = 3


If FindElementFruitStructure(fruit(),"apple")
  Debug "The fruit called " + fruit()\name + " has colour #" + Str(fruit()\colour)
EndIf

If FindElementFruitStructure(fruit(),"orange")
  Debug "The fruit called " + fruit()\name + " has colour #" + Str(fruit()\colour)
EndIf

If FindElementFruitStructureByColour(fruit(), 2)
  Debug "The fruit with colour #" + Str(fruit()\colour) + " is " + fruit()\name
EndIf

If findelementfruitstructurebycolour(fruit(), 34) = 0
  Debug "no element with colour #34?!? who stole my strawberries?"
EndIf

Re: FindListElement() and FindStructuredListElement()

Posted: Tue Jul 13, 2010 7:01 pm
by Seymour Clufley
Thank you, Trond. :)