Autore Topic: Accedere all'ennesimo elemento di una Collection  (Letto 571 volte)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.307
  • Ne mors quidem nos iunget
    • Mostra profilo
Accedere all'ennesimo elemento di una Collection
« il: 04 Giugno 2014, 16:12:42 »
Vorrei riportarvi questa discussione apparsa nella M.L. ufficiale:

" Occasionally, and unfortunately for me lately quite frequently, I have
found a need to access the first or last item in (or perhaps better "the
first or last item added to")  a collection regardless of key values (and
by extension I could envisage a need to access the nth item in a collection
regardless of the key value). There does not seem to be an elegant solution
to this - or maybe just that I am incapable of developing an elegant solution to this.

"First" can be achieved by using the For Each construct and
unconditionally Break'ing the iteration on the first loop. This smells like
using a sledge hammer to crush an ant.
"Last" I have achieved after a manner, but the mechanism is too
embarrassing to reveal.
"nth" I am reluctant to attempt.

Any clues?

 --
 B Bruen
"


" If I remember correctly Benoit warned that collections doesn't necessarily
keep the items in order. But I don't know what would make it to lose the
order. Maybe he will enlighten the issue.
Anyway I suggest you use array of objects, which you declare extra property "Key".

jussi
"


" AFAIK, Collection is a hash table and of course, you cannot assume a
particular order of keys in a hash table.

But Bruce apparently doesn't care about an *order* but only that the
elements can be addressed bijectively by the integers in [0, .Count).

But the collection isn't meant to allow you to do that because elements
are addressed by strings, not integers and the integer addressing isn't
meaningful to people other than Bruce in his particular application :-)

HOWEVER, and that's my proposal, an integer index does make sense in the
AvlTree class in gb.data which is otherwise similar to Collection (i.e.
normally uses strings as indices, etc.), because we can traverse the keys
in an AvlTree in order.

If you can use AvlTree instead of the normal Collection in your application,
I will add functionality to get the n-th element of an AvlTree. Otherwise,
we must hack Collection for this special purpose.

And I don't think Benoit will make that change mainline (because it really
has no sense, under normal circumstances, to use integers to address a
string-built hash table) -- or Benoit adds a .Data property, if that is
possible at all, similar to that of the array classes...?

I don't know but my offer holds.

Regards,
Tobi
"


" Oh, I just saw the "added to" bit. That's not possible with AvlTree and also
won't be with Collection.

Then I suppose that you create a custom Collection class and make it record
the first and last items added. For the general case of the n-th added item,
you really need to sort your keys by the point in time they're inserted and
that's plainly an array using the Add() method.

Generally, if you want to have the same data *sorted* in different ways (and
you want "sorted" because otherwise you would need to loop through the data
which you don't want), it sounds plausible that you need the data twice, but
in diffent containers and sorted differently.

Tobi
"


" >For the general case of the n-th added item,
> you really need to sort your keys by the point in time they're inserted and
> that's plainly an array using the Add() method.

My first question is why not just use an Array full-stop: by
definition that is the structure for accessing
items by order.

> Generally, if you want to have the same data *sorted* in different ways (and
> you want "sorted" because otherwise you would need to loop through the data
> which you don't want), it sounds plausible that you need the data twice, but
> in diffent containers and sorted differently.

Correct.
if the "things" in question are Objects of any type, then internally
what's being held in the Array or Collection are pointers
to the objects, so extra memory use is minimal. In this case IMHO the
most graceful  and efficient solution is to have both an Array and a
Collection of the same objects.

If that doesn't work then I'd have a String[] holding the keys to the
collection, this means two lookups so a bit of a speed penalty (but
Gambas is fast at this stuff, I doubt you'd notice)

Ian
"


" That is my understanding also. But they always seems to be in order they
have been added, when you iterate them with "For Each ...".

What would cause the disorder?

Jussi
"


" There are in order by design (the hash table elements are linked both by
hash slot *and* insertion order).

But I don't guarantee that this non-official feature won't be removed.

Regards,

--
Benoît Minisini
"
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.158
  • Tonno verde
    • Mostra profilo
Re: Accedere all'ennesimo elemento di una Collection
« Risposta #1 il: 04 Giugno 2014, 16:35:56 »
Si l'avevo seguita, ma tu ti fideresti a usare qualcosa di non ufficiale che come detto un domani può non funzionare più?
Io no, e poi grazie a sanmidi io di Collection non ne ho mai avuto di bisogno  ;D
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.307
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Accedere all'ennesimo elemento di una Collection
« Risposta #2 il: 04 Giugno 2014, 16:54:52 »
ma tu ti fideresti a usare ...

...la mia intenzione è semplicemente riportare la discussione.
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Orionis

  • Gambero
  • **
  • Post: 58
    • Mostra profilo
    • BoxIdee
Re: Accedere all'ennesimo elemento di una Collection
« Risposta #3 il: 04 Giugno 2014, 22:52:51 »
Anch'io l'avevo appena letta e sinceramente mi ero chiesto il senso della domanda.
Nel progetto che sto portando in Gambas uso le Collection e mi trovo bene, nel senso che la Key è più che sufficiente per gestire la collezione in qualsiasi modo. Anzi, proprio per il senso esplicito di collezione identificata da una chiave di ricerca, non ha per me alcuna ragione di esistere una numeralità degli elementi.

Ho scoperto invece una peculiarità che mi lascia un pò basito...ma questo sarà l'oggetto della prossima domanda che posterò, ahi..ahi.

P.S, domandina a San Midi: ma quante lingue leggi ? a quando una ciitazione dal gruppo utenti finnici ?

Neanche gli Dei...possono nulla...contro la stupidità umana?

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.307
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Accedere all'ennesimo elemento di una Collection
« Risposta #4 il: 05 Giugno 2014, 00:37:31 »
P.S, domandina a San Midi: ma quante lingue leggi ?
Io credo che San Midi parli con la lingua dei musici.

Ora, orsù , leviamo a lui una lode:

" O San Midi bendetto,
  io mi prostro con rispetto:
  io confido solo in te,
  io m'affido solo a te.
"
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.307
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Accedere all'ennesimo elemento di una Collection
« Risposta #5 il: 05 Giugno 2014, 01:47:15 »
...continua...


" OK, thanks for the answer! But can you elaborate bit further? If the
insertion order is no longer kept, then what dictates the order "For Each"
will enumerate the items? Order of memory addresses?

I mean would the enumeration order be unchanging, but when new item is
added it would be inserted in random (practically from user perspective)
position of the enumeration?


Jussi
"


" In some languages, FOR EACH doesn't guaranty the order of the items
processed. It only guaranties you will process each item in the collection.
I think it is a bad habit to use For Each when order of processing is
important. Unless you are using an array or other data structure that is
known to maintain order. A linked list or array would be a better choice. I
haven't followed all this thread but I am sure that has already been
suggested... The other option is to implement your own ordered collection.
But wouldn't an array of object be easier?

randall
"
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.307
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Accedere all'ennesimo elemento di una Collection
« Risposta #6 il: 05 Giugno 2014, 14:03:23 »
...continua...


" If the key values aren't important then use something like
     Collection.add(Value,str(Collection.count+1))
then you can access any given item by
   Value=Collection[str(Index)]

VonZorch
"


" >FOR EACH doesn't guaranty the order of the items
> processed. It only guaranties you will process each item in the collection.
> I think it is a bad habit to use For Each when order of processing is
> important.


I agree and that is not my requirement. I only need to know when order
changes (if Benoit changes the implementation). Example if I remove one
item, does the enumeration order of rest change? If not, I have no problems.


>The other option is to implement your own ordered collection.
> But wouldn't an array of object be easier?


I choose to use collection, because I have long list of objects and mostly
I need to access them individually and fast. If I would use array I would
have to enumerate them to find the object I wanted to access. Or constantly
update index table when object is removed.

Jussi
"


" Thanks to all for their interest an input here.  At the very least it has helped me to crystallize what my problem is.

I may have over generalised my problem. So I'll try to explain.

The issue is, as some have realised, the temporal order in which things are added to the collection, not some order imposed by information represented by the key or some other value of the object. Primarily, I need to find out what is the key of the last item added to the collection. Secondly, there is sometimes a need to find out what is the key of the first item that was added to the collection since the last time it had zero members.  I don't really (yet) have a need to find the key of the nth item that was added, but I can foresee given the current goals of the project that this need will come up in the future. I'll just talk about the primary goal here.

A semi-optimal solution to my particular situation would be if the collection were to raise an "Added(Key As String)" event when a new item was added.  It is only semi-optimal because that would mean processing would be invoked for each and every addition to the set.

What I have at the moment is an asynchronous "process" (actually it is a Timer event handler) that uses For Each to find the last added  item. Now, the comments that the For Each iteration in insertion order is not necessarily to be trusted are exactly the reason I started this thread. Within the "time quantum" defined by the Timer, zero one or more items could have been added.  It is only necessary for me to process the last added item, hence that is why the event driven idea above is only semi optimal.

Again, the fact that this is a collection and not an array is (unfortunately) a "given".  It is a collection and there is no reasonably economical solution, it would involve re-writing an application suite of over three years generation.


> If the key values aren't important then use something like
>      Collection.add(Value,str(Collection.count+1))
> then you can access any given item by
>    Value=Collection[str(Index)]


No, the key values are important (to the rest of the application). It's just that in this particular instance all I need to get at is the last or first item that was added.

Bruce
"


" An interesting thought just occurred, almost totally unrelated to this thread.

Is a gb.db Result a collection or an array?  It is hard to tell from the help

This class represents the result of a SQL request.
This class is not creatable.
This class acts like a read / write array.
This class is enumerable with the FOR EACH keyword.

but then I cannot access the first item via "MyResult[0]"
It looks like a special array with a strange form of _get().

?

--
B Bruen
"
« Ultima modifica: 05 Giugno 2014, 14:05:33 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »