For what it's worth below an implementation I've started toying with a
while ago. A dictionary here is a boxed pair of lists representing ordered
and uniq keys and values.

regards,
 Danil

== Transcript ==

   [d1 =: dnew               NB. empty dictionary is a pair of empty lists
┌┬┐
│││
└┴┘

   (1 2 3) d1 dmap 'one';'two';'three'    NB.  adding to dictionary x -
keys, y values,  by default stores a typed lists when possible
┌─────┬───────────────┐
│1 2 3│┌───┬───┬─────┐│
│     ││one│two│three││
│     │└───┴───┴─────┘│
└─────┴───────────────┘
   d1 =: (1 2 3) d1 dmap 'one';'two';'three'


   d1 dgetv 2        NB. getting a value
┌───┐
│two│
└───┘
   d1 dgetv 3 2 1     NB. or several at once
┌─────┬───┬───┐
│three│two│one│
└─────┴───┴───┘
   d1 dgetv 0         NB. if key is absent, that is an index error
|index error
|   (keys i.y)    {vals['keys vals'=.m

    [d2 =: ('ONE';'TWO';'THREE') d1 dmap 1 2 3      NB. adding to a
dictionary is the same dmap typed list is demoted to a boxed list by
necessity
┌─────────────────────┬─────────────────────┐
│┌─┬─┬─┬───┬───┬─────┐│┌───┬───┬─────┬─┬─┬─┐│
││1│2│3│ONE│TWO│THREE│││one│two│three│1│2│3││
│└─┴─┴─┴───┴───┴─────┘│└───┴───┴─────┴─┴─┴─┘│
└─────────────────────┴─────────────────────┘
   d2 =: ('ONE';'TWO';'THREE') d1 dmap 1 2 3        NB. now both keys and
vals should be boxed
   d2 dgetv 'ONE';1
┌─┬───┐
│1│one│
└─┴───┘

   0 d2 dgetv 'NOT PRESENT';'ONE';'TWO'             NB. dyadic dgetv to get
a default value x if a key is not there
┌─┬─┬─┐
│0│1│2│
└─┴─┴─┘

d1 dadd d2 NB. combining the two - right keys overwrite left keys

┌─────────────────────┬─────────────────────┐

│┌─┬─┬─┬───┬───┬─────┐│┌───┬───┬─────┬─┬─┬─┐│

││1│2│3│ONE│TWO│THREE│││one│two│three│1│2│3││

│└─┴─┴─┴───┴───┴─────┘│└───┴───┴─────┴─┴─┴─┘│

└─────────────────────┴─────────────────────┘

d1 dadd~ d2 NB. order matters

┌─────────────────────┬─────────────────────┐

│┌───┬───┬─────┬─┬─┬─┐│┌─┬─┬─┬───┬───┬─────┐│

││ONE│TWO│THREE│1│2│3│││1│2│3│one│two│three││

│└───┴───┴─────┴─┴─┴─┘│└─┴─┴─┴───┴───┴─────┘│

└─────────────────────┴─────────────────────┘

d2 dsub d1 NB. subtracting -- left keys removed

┌───────────────┬───────┐

│┌───┬───┬─────┐│┌─┬─┬─┐│

││ONE│TWO│THREE│││1│2│3││

│└───┴───┴─────┘│└─┴─┴─┘│

└───────────────┴───────┘



(1;'THREE') drmk d2 NB. removing keys

┌─────────────┬───────────────┐

│┌─┬─┬───┬───┐│┌───┬─────┬─┬─┐│

││2│3│ONE│TWO│││two│three│1│2││

│└─┴─┴───┴───┘│└───┴─────┴─┴─┘│

└─────────────┴───────────────┘




    dkvs d1                                        NB. keys - values pairs
┌─┬─────┐
│1│one  │
├─┼─────┤
│2│two  │
├─┼─────┤
│3│three│
└─┴─────┘

   ((2*[) ; ]) ddokv d1                            NB. dkvs above is
implemented as an adverb applying ; between k and v, u could be something
else
┌─┬─────┐
│2│one  │
├─┼─────┤
│4│two  │
├─┼─────┤
│6│three│
└─┴─────┘
== Implementation ==

samelength =: =&:#

matchitemshape =: -:&:(}.@:$)


joinboxed =: ,&:(boxopen"_1)

coalesce =: joinboxed`(, :: joinboxed)@. matchitemshape


dpack=: 13 : 'x;<y'

dnew =: ''dpack''

dkeys =: 0&{::

dvals =: 1&{::

ddokv =: 1 : 'dkeys (u&[)"_1 dvals'

dkvs =: ; ddokv

dlen =: #@:dkeys

dchk =: ((2=#) *. (dkeys samelength dvals) *. ([:(-:~.)dkeys)) :: 0 NB.
boxed pair of samelength keys and vals, keys uniq

dadd =: 4 : '(dkeys y) x dmap (dvals y)'

dsub =: 4 : '(}:(dkeys y) coalesce {.dkeys x) drmk x'


drmk =: 4 : 0

'keys values' =: y

mask =: -. keys e. x

(mask#keys) dpack (mask#values)

)


drmv =: drmk &.|.


dgetv =: 1 : 0

(keys i. y) { vals [ 'keys vals' =. m

:

(keys i. y) { vals [ vals =. vals coalesce x [ 'keys vals' =. m

)


dmap =: 1 : 0 NB. x are keys, y are vals

:

assert. x samelength y NB. enforce 1:1 mapping between keys and vals

'keys vals' =. m

keys =. keys coalesce x [ vals =. vals coalesce y

revseive =. ~:&.|. keys NB. keys can be not uniq, reverse seive to
'overwrite' by the last key-value pair

(revseive # keys) dpack (revseive # vals)

)




вт, 1 февр. 2022 г. в 16:56, Alex Shroyer <ashro...@gmail.com>:

> In the past, I have implemented 2-column "pseudo-dictionaries" in J. It
> works, but feels very awkward compared to working with arrays:
>    ]d=: (;:'a b c'),.1 2 3;'foo bar';(<;:'x y z')
> ┌─┬───────┐
> │a│1 2 3  │
> ├─┼───────┤
> │b│foo bar│
> ├─┼───────┤
> │c│┌─┬─┬─┐│
> │ ││x│y│z││
> │ │└─┴─┴─┘│
> └─┴───────┘
>    get=: {{((<,x) I.@E. {."1 y) { {:"1 y}}
>    'b' get d
> ┌───────┐
> │foo bar│
> └───────┘
>
> What I mean by awkward is not only the verbosity required to implement a
> 'get' verb, but also the extra awkwardness when extending this simple
> dictionary to be more useful:
> When I add a key to d which is an atom (rather than a char array), I need
> to rewrite my get verb.
> Or, if I restrict keys in dictionaries to only symbol values, then it
> becomes more difficult to use real-world data as keys.
>
> I think if J syntax supported this datatype natively, then the above 'get'
> verb would just be
> 'b' { dict
> Which is much better as a tool of thought.
>
>
> To answer Henry's questions:
>
> My definition of a dictionary is:
> A collection where data is organized by key, where keys can be symbols,
> strings, or numbers (or possibly other data types) and values can be
> arbitrary J data.
>
> Essential dictionary operations are:
> - create/read/update/delete by key
> - query if key exists
> - enumerate all keys (returns an array of boxed keys)
> - enumerate all values (returns an array of boxed values)
> - merge two dictionaries e.g. (Z=: X merge Y) and if X and Y share any key,
> then Z gets the key/value pair from Y
>
> Nice features to have, but not necessary:
> - keys are stored in J's sorting order
> - dictionaries can be serialized/deserialized for persistent disk storage
> or for sending to other processes
>
> On Tue, Feb 1, 2022 at 8:37 AM ethiejiesa via Programming <
> programm...@jsoftware.com> wrote:
>
> > Maybe negative anwsers could help clarify things?
> > - Why is a 2-column inverted table, together with appropriate access
> > idioms,
> >   not a dictionary?
> > - HPC folk have been representing trees as cleverly-arranged arrays for
> > years,
> >   apparently. Why are tries [0] not dictionaries?
> >
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to