This is the hashmap implementation I wrote a while ago, using separate 
chaining, and using J's OO functionality. Bear in mind I am not a J expert, and 
when I wrote this I knew even less J.
I am pretty sure others have written better implementations, but anyway, this 
may be useful as a reference for writing your own. The hash function is
pretty crummy, I was going to attempt to implement murmurhash in J, but never 
got around to doing it. Also there is no verb to output the map as json, or 
import json.

I lost a little interest in this after realizing J' OO has no introspection 
ability. So putting one hashmap inside another (as in embedding a json 
dictionary in another json dictionary)
leads to a loss of information, as you have to remember that the value is a J 
object , and not a boxed literal.



coclass 'HashMap'
entries=: ''
count=: ''
MAX=: 20

NB. Initialize and create buckets
create=: monad define
for_j. i. MAX do.
  entries=: entries, (conew 'Entry')
end.
)

NB. Gets the size of the hashmap,
NB. number of key/value pairs.
size=: monad define
count=. 0
for_j. i. MAX do.
  ent=. j{entries
  if. isSet__ent do. count=. count + get_size__ent ''
  end.
end.
count
)

NB. set a new key value pair.
NB. Should be boxed pair (key;value)
set=: monad define
rk=. >0{y NB. raw key
hk=. hash rk NB. hashed key
val=. >1{y NB. value
i=. conew 'Entry'
create__i rk;hk;val
hk append i
''
)

NB. Returns list of all key value pairs
NB. in an arbitrary order.
enumerate=: monad define
result=. ''
for_j. i. MAX do.
  ent=. j{entries
  if. isSet__ent do.
    result=. result, (enumerate__ent '')
  end.
end.
result
)


NB. Append the new Entry to the hashmap.
append=: dyad define
ent=. x { entries
newent=. y
NB. if empty slot, put new item in it.
if. 0 = isSet__ent do.
  entries=: y x} entries
NB. if not empty, but raw keys are identical, refill.
elseif. rawKey__ent -: rawKey__newent do.
  entries=: newent x} entries
NB. else append to the last in linkedlist
elseif. 1 do.
  append_to_last__ent y
end.
)

NB. Get the value for the given key.
get=: monad define
ky=. y
hk=. hash ky
ent=. hk{entries
if. 0 = isSet__ent do. 'ERROR' return.
elseif. key__ent -: hk do.
  matches__ent ky
end.
)

NB. Removes a single entry form the hashmap, if
NB. the given key matches the key of the entry.
remove=: monad define
ky=. y
hk=. hash ky
ent=. hk{entries
NB. if no entry, then return.
if. 0 = isSet__ent do. 0
NB. keys match...
elseif. key__ent -: hk do.
NB. check if raw keys match...
  if. ky -: rawKey__ent do.
NB. linked list is 0 so remove this item.
    if. 0 = # next__ent do.
      reset__ent ''
      1
NB. linked list has elements so put
NB. next element in bucket (becomes head of list).
    else. entries=: next__ent hk} entries
      reset__ent ''
      1
    end.
NB. raw keys do not match, check next element.
  else.
    nextent=. next__ent
    ent remove_from_list__nextent y
  end.
end.
)

NB. Returns 1 if vey value pair exists for the
NB. given key, otherwise returns 0.
contains_value=: monad define
ky=. y
hk=. hash ky
ent=. hk{entries
if. 0 = isSet__ent do. 0
elseif. key__ent = hk do.
  contains__ent ky
end.
)

NB. Hash the key.
hash=: monad define
h=. a.i.": y
h=. +/h
h1=. 3 (33 b.) h
h2=. 13 (33 b.) h
h=. h XOR h1 XOR h2
h=. h XOR (7 ( 33 b.) h)
MAX | h
)

destroy=: codestroy


NB. =============== ENTRY CLASS =============

NB. Entry class contains key value pair and "pointer"
NB. to potential next entry in LinkedList fashion.
coclass 'Entry'
key=: ''                NB. The key (hashed)
value=: ''      NB. The value
next=: ''               NB. The next value, if any
rawKey=: ''     NB. The raw, unhashed, key
isSet=: 0               NB. flag for instantiated or not.

NB. Instantiate the Entry object.
create=: 3 : 0
rawKey=: >0{y
key=: >1{y
value=: 2}.y NB. strip the first two
isSet=: 1
)

NB. Returns 1 if this Entry contains the key
NB. value pair for the given key.
contains=: monad define
rk=: y
if. isSet = 0 do. 0
elseif. (<rawKey) = <rk do.
  1
elseif. 0 = # next do. 0
elseif. 1 do.
  contains__next y
end.
)

NB. Returns this key value pair and the
NB. list of key value pairs of the tail of the 
NB. linked list.
enumerate=: monad define
if. 0 = # next do.
  <(rawKey; value)
else.
  (<(rawKey;value)),( enumerate__next '')
end.
)

NB. Tests if the key matches and if so returns the value,
NB. else sends key to the next item in linkedlist.
matches=: monad define
rk=. y
rk =. ($rawKey) $ rk
if. isSet = 0 do. 'ERROR' return.
elseif. (rawKey) -: (rk) do.
  value
elseif. 1 do.
  matches__next y
end.
)

NB. Removes this item from the current linked list.
remove_from_list=: dyad define
rk=. y NB. a raw key
last=. x NB. the last entry in this list
if. rk -: rawKey do.
  next__last=: next NB. relink the last/next items.
  reset ''
  1
elseif. 0 = # next do. 0
elseif. 1 do. next__last remove_from_list__next y end.
)


get_size=: monad define
if. 0 = # next do. 1
else. 1 + get_size__next ''
end.
)

append_to_last=: monad define
if. 0 = # next do.
  next=: y
else.
  append_to_last__next y
end.
)

NB. Resets this item.
reset=: monad define
isSet=: 0
key=: ''
value=: ''
next=: ''
rawKey=: ''
)

destroy=: codestroy



NB. usage
H=: '' conew 'HashMap'
set__H 'key';'value'
set__H 'another key'; 4
remove__H 'key'
get__H 'another key'
enumerate__H '' NB. list all key-value-pairs
--------------------------------------------
On Mon, 12/4/17, Andrew Dabrowski <[email protected]> wrote:

 Subject: Re: [Jprogramming] delete item; ass. lists
 To: [email protected]
 Date: Monday, December 4, 2017, 10:18 AM
 
 Can you locate your code?
 
 
 On 12/03/2017
 06:52 PM, Henry Rich wrote:
 > Yes;
 I've done that before.  It might be worth seeing how
 well we 
 > could make such an addon
 perform before making changes to the JE.
 >
 > Henry Rich
 >
 > On 12/3/2017 6:47 PM,
 bill lam wrote:
 >> Can this be
 implemented using j script addon?
 >>
 >> On Dec 4,
 2017 5:26 AM, "Henry Rich" <[email protected]>
 wrote:
 >>
 >>>
 Perhaps we shouldn't try to make a full datatype for
 associative 
 >>> arrays,
 >>> but just a set of functions
 (foreigns, or (m h.) ) that do what's 
 >>> needed.
 >>>
 >>> We
 would need to decide what's needed.
 >>>
 >>>
 hashtable =: keys create values
 >>>
 indexes =: hashtable lookup keys (like i.)
 >>> values =: hashtable fetch
 indexes   (like {)
 >>> hashtable
 =: hashtable add keys;values
 >>>
 hashtable =: hashtable delete indexes
 >>>
 >>> That
 would not be the hardest thing to implement; perhaps we
 should 
 >>> start
 >>> a strawman in
 Interpreter/Requests.
 >>>
 >>> Henry Rich
 >>>
 >>>
 >>> On 12/3/2017 4:06 PM, Marshall
 Lochbaum wrote:
 >>>
 >>>> The associative lists that
 Andrew is talking about (also called 
 >>>> maps or
 >>>> dictionaries) are essentially
 the same as JSON objects (more 
 >>>> precisely,
 >>>> JSON objects are maps whose
 keys are strings). There's no need for 
 >>>> them
 >>>> to be used in a particularly
 low-level way, although the primitives 
 >>>> used
 >>>> to manipulate them would have
 to be different from J's array 
 >>>> primitives.
 >>>> Examples might be combining
 two maps but giving preference to one of
 >>>> them when they conflict, or
 inverting a map by swapping keys and 
 >>>> values.
 >>>>
 >>>> Lisp stands for "list
 processing", and its fundamental datatype is the
 >>>> linked list, composed of
 value-reference pairs. These aren't 
 >>>> related to
 >>>> associative arrays, at least
 not any more than they are related to any
 >>>> other datatype.
 >>>>
 >>>> I feel pretty strongly that an
 associative array type is missing in J,
 >>>> but it's understandable
 given how hard such a type would be to specify
 >>>> and implement. That
 doesn't make it any easier to live without them,
 >>>> though.
 >>>>
 >>>> Marshall
 >>>>
 >>>> On Sun, Dec 03, 2017 at
 01:50:43PM -0500, Raul Miller wrote:
 >>>>
 >>>>> <<< means
 "box three times"
 >>>>>
 >>>>>      <2
 >>>>> ┌─┐
 >>>>> │2│
 >>>>> └─┘
 >>>>>      <<2
 >>>>> ┌───┐
 >>>>> │┌─┐│
 >>>>> ││2││
 >>>>> │└─┘│
 >>>>> └───┘
 >>>>>      <<<2
 >>>>> ┌─────┐
 >>>>> │┌───┐│
 >>>>> ││┌─┐││
 >>>>> │││2│││
 >>>>> ││└─┘││
 >>>>> │└───┘│
 >>>>> └─────┘
 >>>>>
 >>>>> See also the documentation
 on the index operation (Henry gave you a
 >>>>> reference for that).
 >>>>>
 >>>>> Also, as I understand it,
 JSON has only a loose relationship with
 >>>>> a-lists. My understanding
 of them is that they are the fundamental
 >>>>> datatype provided by the
 lisp / scheme / .. family of languages.
 >>>>> Basically, you're
 working with pointer chasing. In J, you can use
 >>>>> indices or names as
 references, if you want to build a workalike - 
 >>>>> but
 >>>>> usually it's just not
 worth the bother.
 >>>>>
 >>>>> And that
 "encode" method is building a name based on an
 arbitrary
 >>>>> string. You
 should probably think of it as a hash function. But
 >>>>> there's a typo - there
 should be a space after the v in inv. But this
 >>>>> suggests also that
 rosettacode is having bitrot issues with its
 >>>>> storage system, and that
 has all sorts of unpleasant implications.
 >>>>> Basically, you are not
 going to be able to use rosettacode
 >>>>> implementations - in the
 general case - unless you are prepared to
 >>>>> debug them (which kind of
 defeats the purpose of having the site in
 >>>>> the first place.) ...
 wait, no.. when I go to that rosettacode 
 >>>>> page, I
 >>>>> see a space after the
 'inv' keyword. Well.. it could still be bitrot,
 >>>>> but perhaps at the
 cloudfront level rather than on the site itself...
 >>>>>
 >>>>> Thanks,
 >>>>>
 >>>>> -- 
 >>>>> Raul
 >>>>>
 >>>>>
 >>>>>
 >>>>> On Sun, Dec 3, 2017 at
 1:24 PM, Andrew Dabrowski 
 >>>>> <[email protected]>
 >>>>> wrote:
 >>>>>
 >>>>>> 1. Yes, I should been
 more specific: I wanted to know the 
 >>>>>> idiomatic way
 >>>>>> to
 >>>>>> delete the nth item of
 a list, so I think <<< is what I was 
 >>>>>> looking for.
 >>>>>>
 >>>>>> What is <<<
 called and where is it documented?
 >>>>>>
 >>>>>> 2. Not sure what you
 mean by "Their focus is on micromanaging the
 >>>>>> sequence
 >>>>>> of operations." 
 A-lists are built into just about every other 
 >>>>>> modern
 >>>>>> language because
 they're so useful at managing information.  Does 
 >>>>>> J not
 >>>>>> support JSON for web
 interoperability?
 >>>>>>
 >>>>>> One example is using
 an a-list as a structured object, without 
 >>>>>> having
 >>>>>> to get
 >>>>>> into full-blown OO. 
 I could represent the state of a model using an
 >>>>>> a-list
 >>>>>> and then update the
 values over time.
 >>>>>>
 >>>>>> I saw that using
 classes is one alternative
 >>>>>> (https://rosettacode.org/wiki/Associative_array/Creation#J).
 >>>>>>
 >>>>>>
 coclass'assocArray'
 >>>>>>      
 encode=:'z',(a.{~;48  65  97(+ i.)&.>10
 26  26)  {~62x
 >>>>>>
 #.inv256x  #.
 >>>>>>
 a.&i.
 >>>>>>
       get=: ".@encode
 >>>>>>       has=:0 
 <: nc@<@encode
 >>>>>>       set=:4 
 :'(encode x)=:y'
 >>>>>>
 >>>>>> I have absolutely no
 idea what is going on in the encode function. I
 >>>>>> hope
 >>>>>> there are other
 options.
 >>>>>>
 >>>>>>
 >>>>>>
 >>>>>> On 12/03/2017 12:59
 PM, Raul Miller wrote:
 >>>>>>
 >>>>>>> Why do you want to
 delete an item from a list? This is *not* a
 >>>>>>> rhetorical
 question - we have a variety of ways of removing 
 >>>>>>> items from
 >>>>>>> lists and to pick
 the correct mechanism we need to understand 
 >>>>>>> what you
 >>>>>>> are trying to
 accomplish.
 >>>>>>>
 >>>>>>> To illustrate,
 here are a few examples:
 >>>>>>>
 >>>>>>> list=: 2 3 4 5 7 8
 9 10
 >>>>>>>
 >>>>>>>       NB.
 delete specific elements
 >>>>>>>       list -.
 3 5 7
 >>>>>>> 2 4 8 9
 10
 >>>>>>>
 >>>>>>>       NB.
 delete based on a computation
 >>>>>>>      
 (0=1&p: list)#list
 >>>>>>> 4 8 9 10
 >>>>>>>
 >>>>>>>       NB.
 delete based on a range of indices
 >>>>>>>      
 (3&{.,6&}.) list
 >>>>>>> 2 3 4 9 10
 >>>>>>>
 >>>>>>>       NB.
 delete values at certain indices
 >>>>>>>      
 (<<<3 5 6){ list
 >>>>>>> 2 3 4 7 10
 >>>>>>>
 >>>>>>> And then
 there's operations (like outfix) which offer regular
 >>>>>>> abstractions:
 >>>>>>>       3 ]\.
 list
 >>>>>>> 5 7 8 9
 10
 >>>>>>> 2 7 8 9
 10
 >>>>>>> 2 3 8 9
 10
 >>>>>>> 2 3 4 9
 10
 >>>>>>> 2 3 4 5
 10
 >>>>>>> 2 3 4 5 
 7
 >>>>>>>
 >>>>>>> Note that
 "delete from a list" is a dual of "select
 from a list" -
 >>>>>>> maybe a shift in
 perspective can help?
 >>>>>>>
 >>>>>>> As for the lack of
 "a-lists" - again, why do you want them? 
 >>>>>>> Depending
 >>>>>>> on what you are
 trying to do, there's a lot of options. Their 
 >>>>>>> focus is
 >>>>>>> on micromanaging
 the sequence of operations, though, so you 
 >>>>>>> should not
 >>>>>>> expect the
 language to make most of your decisions for you, there
 >>>>>>> (unless of course
 you are working with a language which was
 >>>>>>> specifically
 designed with an "everything should be an
 a-list"
 >>>>>>>
 mentality - but that's not J).
 >>>>>>>
 >>>>>>> Thanks,
 >>>>>>>
 >>>>>>>
 ----------------------------------------------------------------------
 
 >>>>>>>
 >>>>>> For information about
 J forums see 
 >>>>>> http://www.jsoftware.com/forums.htm
 >>>>>>
 >>>>>
 ----------------------------------------------------------------------
 
 >>>>>
 >>>>> For information about J
 forums see 
 >>>>> http://www.jsoftware.com/forums.htm
 >>>>>
 >>>>
 ----------------------------------------------------------------------
 >>>> For information about J forums
 see http://www.jsoftware.com/forums.htm
 >>>>
 >>>
 >>>
 ---
 >>> This email has been checked
 for viruses by AVG.
 >>> http://www.avg.com
 >>>
 >>>
 ----------------------------------------------------------------------
 >>> For information about J forums see
 http://www.jsoftware.com/forums.htm
 >>
 ----------------------------------------------------------------------
 >> For information about J forums see http://www.jsoftware.com/forums.htm
 >
 >
 ----------------------------------------------------------------------
 > For information about J forums see http://www.jsoftware.com/forums.htm
 
 ----------------------------------------------------------------------
 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