Author Topic: Associative Arrays (Rosetta)  (Read 7514 times)

0 Members and 1 Guest are viewing this topic.

Charles Pegge

  • Guest
Associative Arrays (Rosetta)
« on: June 28, 2012, 03:14:31 PM »
Very basic implementation:

Code: OxygenBasic
  1.  
  2. def n 200
  3.  
  4.  
  5. Class AssociativeArray
  6. '=====================
  7.  
  8.   indexbase 1
  9.   string s[n]
  10.   sys    max
  11.  
  12.   method find(string k) as sys
  13.   sys i,e
  14.   e=max*2
  15.   for i=1 to e step 2
  16.     if k=s[ i ] then return i
  17.   next
  18.   end method
  19.  
  20.   method dat(string k) as string
  21.   sys i=find(k)
  22.   if i then return s[ i+1]
  23.   end method
  24.  
  25.   method dat(string k, d) as sys
  26.   sys i=find(k)
  27.   if i=0 then
  28.     if max>=n
  29.       print "Array overflow" : return 0
  30.     end if
  31.     max+=1
  32.     i=max*2-1
  33.     s[ i ]=k
  34.   end if
  35.   s[ i+1]=d
  36.   return i
  37.   end method
  38.  
  39. end class
  40.  
  41.  
  42. '====
  43. 'TEST
  44. '====
  45.  
  46. AssociativeArray A
  47.  
  48. 'fill
  49. A.s<={"shoes","LC1",  "ships","LC2",  "sealingwax","LC3",  "cabbages","LC4",  "kings","LC5"}
  50. A.max=5
  51. 'access
  52. print A.dat("ships")       'result LC2
  53. A.dat("computers")="LC99"  '
  54. print A.dat("computers")   'result LC99
  55.  
  56.  

http://rosettacode.org/wiki/Associative_arrays/Creation


Charles

Aurel

  • Guest
Re: Associative Arrays (Rosetta)
« Reply #1 on: October 27, 2013, 02:35:03 AM »
hi Charles
What you think about using associative array as container for array in interpreter?

Charles Pegge

  • Guest
Re: Associative Arrays (Rosetta)
« Reply #2 on: October 27, 2013, 09:27:03 PM »
I think they are good for small data sets. not very efficient but easy to use.

Here is another implementation, using only 1 string for storage. The storage capacity is flexible, and easy to store.

Code: OxygenBasic
  1. Class AssociativeArray  
  2. '=====================  
  3.  
  4.   bstring s,c1,c2,c3
  5.   sys     max  
  6.   '
  7.  method find(string k) as sys  
  8.   sys i=instr(s, c1+k+c2)
  9.   if i>max then i=0
  10.   return i
  11.   end method  
  12.   '
  13.  method dat(string k) as string
  14.   'GET  
  15.  sys i=find k
  16.   if i then
  17.     i=instr i,s,c2
  18.     sys j=instr(i,s,c3)
  19.     if j then return mid s,i+1,j-i-1
  20.   end if
  21.   end method  
  22.   '
  23.  method dat(string k, d) as sys
  24.   'PUT
  25.  sys i
  26.   if max=0 then
  27.     'SET FIELD MARKERS
  28.    c1=chr(1) : c2=chr(2) : c3=chr(3)
  29.   else
  30.     i=find k
  31.   end if
  32.   if i=0 then
  33.     'APPEND
  34.    sys m=max+len(k)+len(d)+3
  35.     if m>len s then
  36.       s+=nuls 0x1000+m-max 'stretch at least 4k
  37.    end if
  38.     mid s,max+1,c1+k+c2+d+c3
  39.     i=max
  40.     max=m
  41.   else
  42.     'REPLACE
  43.    i+=len(k)+2
  44.     sys j=instr(i,s,c3)
  45.     if j then
  46.       'INSERT DATA
  47.      s=left(s,i-1)+d+c3+mid(s,j+1)
  48.       max=len s
  49.     end if
  50.   end if  
  51.   return i  
  52.   end method
  53.  
  54.   method clear()
  55.   s="" : c1="" : c2="" : c3="" : max=0
  56.   end method
  57.  
  58.   method fill(sys n,...)
  59.   sys i
  60.   indexbase 0
  61.   bstring w at @param
  62.   n+=n
  63.   for i=1 to n step 2
  64.     dat w(i),w(i+1)
  65.   next
  66.   end method
  67.  
  68. end class  
  69.  
  70.  
  71. '====  
  72. 'TEST  
  73. '====  
  74.  
  75. AssociativeArray A  
  76.  
  77. A.fill 5,"shoes","LC1",  "ships","LC2",  "sealingwax","LC3",  "cabbages","LC4",  "kings","LC5"
  78. 'print A.s
  79. print A.dat("ships")       'result LC2  
  80. A.dat("computers")="LC99"  '  
  81. print A.dat("computers")  'result LC99
  82. A.clear()
  83.  

kryton9

  • Guest
Re: Associative Arrays (Rosetta)
« Reply #3 on: November 04, 2013, 10:10:27 PM »
I missed this post somehow. Good thing I clicked on Home instead of just Show unread posts...visit.

Cool stuff Charles, but I should never be surprised by what you come up with.

Charles Pegge

  • Guest
Re: Associative Arrays (Rosetta)
« Reply #4 on: November 05, 2013, 07:26:00 AM »
They are useful for typeless languages - less so for languages that support types and OOP.

Frankolinox

  • Guest
Re: Associative Arrays (Rosetta)
« Reply #5 on: November 07, 2013, 04:01:36 AM »
the last "Class AssociativeArray" example doesn't run here, I dont know why? Is there a new oxygen dll needed for running? I've got an error about "class" thingy, oxygen cannot read that one.

Aurel

  • Guest
Re: Associative Arrays (Rosetta)
« Reply #6 on: November 07, 2013, 04:49:48 AM »
work for me...
To better understand how this work and how this can be used
i little bit rearange fill method...well oxygen have really really almost the best way
i have ever see for OOP stuff,even i don't get some things i know something about UDT  ;D
Code: [Select]
Class AssociativeArray 
'===================== 
 
  bstring s,c1,c2,c3
  sys     max 
  '
  method find(string k) as sys 
  sys i=instr(s, c1+k+c2)
  if i>max then i=0
  return i
  end method 
  '
  method dat(string k) as string
  'GET 
  sys i=find k
  if i then
    i=instr i,s,c2
    sys j=instr(i,s,c3)
    if j then return mid s,i+1,j-i-1
  end if
  end method 
  '
  method dat(string k, d) as sys
  'PUT
  sys i
  if max=0 then
    'SET FIELD MARKERS
    c1=chr(1) : c2=chr(2) : c3=chr(3)
  else
    i=find k
  end if
  if i=0 then
    'APPEND
    sys m=max+len(k)+len(d)+3
    if m>len s then
      s+=nuls 0x1000+m-max 'stretch at least 4k
    end if
    mid s,max+1,c1+k+c2+d+c3
    i=max
    max=m
  else
    'REPLACE
    i+=len(k)+2
    sys j=instr(i,s,c3)
    if j then
      'INSERT DATA
      s=left(s,i-1)+d+c3+mid(s,j+1)
      max=len s
    end if
  end if 
  return i 
  end method

  method clear()
  s="" : c1="" : c2="" : c3="" : max=0
  end method

  method fill(sys n,...)
  sys i
  indexbase 0
  bstring w at @param
  n+=n
  for i=1 to n step 2
    dat w(i),w(i+1)
  next
  end method
 
end class 
 
 
'==== 
'TEST 
'==== 
 
AssociativeArray A 
 'fill key-value pair
A.fill 1,"shoes","LC1" 
A.fill 1,"ships","LC2"
A.fill 1,"sealingwax","LC3"
A.fill 1,"cabbages","LC4"
A.fill 1,"kings","LC5"

'print A.s
print A.dat("ships")       'result LC2 
A.dat("computers")="LC99"  ' 
print A.dat("computers")  'result LC99
A.clear()

Aurel

  • Guest
Re: Associative Arrays (Rosetta)
« Reply #7 on: November 07, 2013, 04:59:26 AM »
I think that this can be very good container...
Code: [Select]
Class AssociativeArray 
'===================== 
 
  bstring s,c1,c2,c3
  sys     max 
  '
  method find(string k) as sys 
  sys i=instr(s, c1+k+c2)
  if i>max then i=0
  return i
  end method 
  '
  method dat(string k) as string
  'GET 
  sys i=find k
  if i then
    i=instr i,s,c2
    sys j=instr(i,s,c3)
    if j then return mid s,i+1,j-i-1
  end if
  end method 
  '
  method dat(string k, d) as sys
  'PUT
  sys i
  if max=0 then
    'SET FIELD MARKERS
    c1=chr(1) : c2=chr(2) : c3=chr(3)
  else
    i=find k
  end if
  if i=0 then
    'APPEND
    sys m=max+len(k)+len(d)+3
    if m>len s then
      s+=nuls 0x1000+m-max 'stretch at least 4k
    end if
    mid s,max+1,c1+k+c2+d+c3
    i=max
    max=m
  else
    'REPLACE
    i+=len(k)+2
    sys j=instr(i,s,c3)
    if j then
      'INSERT DATA
      s=left(s,i-1)+d+c3+mid(s,j+1)
      max=len s
    end if
  end if 
  return i 
  end method

  method clear()
  s="" : c1="" : c2="" : c3="" : max=0
  end method

  method fill(sys n,...)
  sys i
  indexbase 0
  bstring w at @param
  n+=n
  for i=1 to n step 2
    dat w(i),w(i+1)
  next
  end method
 
end class 
 
 
'==== 
'TEST 
'==== 
 
AssociativeArray A 
 'fill key-value pair
A.fill 1,"shoes","LC1" 
A.fill 1,"ships","LC2"
A.fill 1,"sealingwax","LC3"
A.fill 1,"cabbages","LC4"
A.fill 1,"kings","LC5"

'print A.s
print A.dat("ships")       'result LC2 
A.dat("computers")="LC99"  ' 
print A.dat("computers")  'result LC99
A.clear()

'new
AssociativeArray arr01

arr01.fill 1,"a","10"
arr01.fill 1,"b","20"
arr01.fill 1,"c","10"

print arr01.dat("b")  ' res 20
arr01.dat("d") = "40"
print arr01.dat("d")  'res 40

Aurel

  • Guest
Re: Associative Arrays (Rosetta)
« Reply #8 on: November 07, 2013, 05:35:43 AM »
And another small example with asci char map with assoc-array
Code: [Select]
Class AssociativeArray 
'===================== 
 
  bstring s,c1,c2,c3
  sys     max 
  '
  method find(string k) as sys 
  sys i=instr(s, c1+k+c2)
  if i>max then i=0
  return i
  end method 
  '
  method dat(string k) as string
  'GET 
  sys i=find k
  if i then
    i=instr i,s,c2
    sys j=instr(i,s,c3)
    if j then return mid s,i+1,j-i-1
  end if
  end method 
  '
  method dat(string k, d) as sys
  'PUT
  sys i
  if max=0 then
    'SET FIELD MARKERS
    c1=chr(1) : c2=chr(2) : c3=chr(3)
  else
    i=find k
  end if
  if i=0 then
    'APPEND
    sys m=max+len(k)+len(d)+3
    if m>len s then
      s+=nuls 0x1000+m-max 'stretch at least 4k
    end if
    mid s,max+1,c1+k+c2+d+c3
    i=max
    max=m
  else
    'REPLACE
    i+=len(k)+2
    sys j=instr(i,s,c3)
    if j then
      'INSERT DATA
      s=left(s,i-1)+d+c3+mid(s,j+1)
      max=len s
    end if
  end if 
  return i 
  end method

  method clear()
  s="" : c1="" : c2="" : c3="" : max=0
  end method

  method fill(sys n,...)
  sys i
  indexbase 0
  bstring w at @param
  n+=n
  for i=1 to n step 2
    dat w(i),w(i+1)
  next
  end method
 
end class 
 
 
'==== 
'TEST 
'==== 
 
'new
AssociativeArray arr01
int n
string cr=chr(13)
string ch="",value,buff=""
'A-Z
'n=65
For n=65 to 90
  value = str(n)
  ch    = chr(n)
    arr01.fill 1,ch,value
    buff = buff + ch + " " + arr01.dat(ch) + cr   
Next n
'asci map from 65-90
print buff

Frankolinox

  • Guest
Re: Associative Arrays (Rosetta)
« Reply #9 on: November 07, 2013, 07:55:03 AM »
my mistake, the problems was caused by the numbers (1.,2.,3. ..) in front of codelines, I deleted all and array example works fine.

Aurel

  • Guest
Re: Associative Arrays (Rosetta)
« Reply #10 on: May 04, 2020, 09:05:47 AM »
Quote
They are useful for typeless languages

Hello Charles

Let say that i want to add Lists() of elements in my interpreter.
Can i use associative array that i can hold different types of elements in that list like:

List{a} = [ "mystring", myInt, myFloat]

Brian Alvarez

  • Guest
Re: Associative Arrays (Rosetta)
« Reply #11 on: May 05, 2020, 08:14:15 AM »
I like them, but they are not for exactly fitted executables. The main problem with associative arrays
in executables is that they could raise runtime errors. I have a half baked implementation:

Code: [Select]
DIM Arr(10) AS ASSOCIATIVE
This way you can do something like:

Code: [Select]
Arr("name") = "Brian"
Arr(0)   = "Something else"
Arr(10) = 29883

But you wouldnt be able to do, for example:

Code: [Select]
FOR Arr(10) = 1 to 10
    ' Some code.
NEXT

 This had a good purpose for CGI scripting though. I will see if i can finish the implementation for Oxygen.

Aurel

  • Guest
Re: Associative Arrays (Rosetta)
« Reply #12 on: May 05, 2020, 11:46:24 AM »
Hi Brian
Quote
The main problem with associative arrays
in executables is that they could raise runtime errors

After i finish core with expression parser and vars,loops i will try to add it .
of course they need test..

runtime errors that is not fine ,they are UDT so that is a problematic part
i will see...
to have List in lang would be fine !

Brian Alvarez

  • Guest
Re: Associative Arrays (Rosetta)
« Reply #13 on: May 07, 2020, 11:46:08 AM »

 I implemented them for simple purposes. Direct values.

 They still dont support storing UDT's or Arrays in them though.

Brian Alvarez

  • Guest
Re: Associative Arrays (Rosetta)
« Reply #14 on: May 07, 2020, 12:26:43 PM »
In the image it does not show, but Ar("something") is also supported.