User:Matthew Brand/collection

From J Wiki
Jump to navigation Jump to search

Matthew Brand

Email: <<MailTo(mtthwbrnd@gmail.com)>>

Collection Object

The collection object collects together a list of objects and provides methods to collate the properties across the collection and the results of calling any method on each object.

Deleting an object from the collection results in its removal from the list and (optionally) the destruction of the removed object.

Example Usage

   NB. Check out the Unique Sequential Number Example (below) to understand some parts of this example.

   load jpath,'~user/classes/collection.ijs'

   NB. Create a simple example class to store a persons name and address.
   coclass 'person'
   cocurrent 'person'
   create =:  3 : 0
	'name address' =:  y
)
   view =: 3 : 0
	name , ' lives at ', address, '.'
)
   destroy =: codestroy
   cocurrent 'base'

   NB. Create a collection object.
   addressbook =: '' conew 'collection'

   NB. Add some persons to the collection. The output is explained in the USN example below.
   add__addressbook ('Patrick';'3 Mill Road') conew 'person'
+-++
|0||
+-++
   add__addressbook ('Bill';'1 Banana Lane') conew 'person'
+-++
|1||
+-++

   NB. The collect__ method runs through the objects in the collection and concatenation the value of the requested property
   collect__addressbook 'name'
+-------+----+
|Patrick|Bill|
+-------+----+
   collect__addressbook 'address'
+-----------+-------------+
|3 Mill Road|1 Banana Lane|
+-----------+-------------+

   NB. The probe verb helps to keep track of objects. It lists a the value of a property if that property and object exists and if the property is literal ... blank otherwise. It is not essential, just useful for understanding what is going on with all those objects. The example below lists the values of the name property for the first 20 objects. Where we see that objects 4 and 5 have names.
   20 probe_collection_ 'name'
0
2
3
4 Patrick
5 Bill
6
7
8
9
10
11
12
13
14
15
16
17
18
19


   NB. Internally the collection is a usn object. See the Unique Sequential Number example below for more details.
   items__addressbook 	NB. The items in the address book (i.e. the person objects)
+-+-+
|4|5|
+-+-+
   sn__addressbook 	NB. The Unique Sequential Numbers (integers) assigned to those objects
0 1

   NB. delete the first person from the address book
   NB. The items__address book are ordered by the object id of the person object, not by name.
   NB. The delete__ method just removes the object from the collection.
   NB. The obdelete__ method also destroys the object being deleted.
   NB. x = 0 to select using and object.
   NB. x = 1 to select using the usn.
   0&obdelete__addressbook {. items__addressbook
1
   20 probe_collection_ 'name'
0
2
3
5 Bill
6
7
8
9
10
11
12
13
14
15
16
17
18
19

   items__addressbook
+-+
|5|
+-+

   NB. Delete item with the first usn. I.e. the last person whose details were entered (like a stack).
   sn__addressbook
1
   1&obdelete__addressbook 0 { sn__addressbook
1
   20 probe_collection_ 'name'
0
2
3
6
7
8
9
10
11
12
13
14
15
16
17
18
19

NB. No items.
   items__addressbook


   NB. Add some persons to the collection
   add__addressbook ('Patrick';'3 Mill Road') conew 'person'
+-++
|2||
+-++
   add__addressbook ('Bill';'1 Banana Lane') conew 'person'
+-++
|3||
+-++
   sn__addressbook NB. Note the usn are always unique (i.e. 2 3 now)
2 3
   items__addressbook
+--+--+
|20|21|
+--+--+

   NB. mcollect__ (monad collect) method calls the function x for each object using parameter y.
   'view' mcollect__addressbook ''
+-----------------------------+----------------------------+
|Patrick lives at 3 Mill Road.|Bill lives at 1 Banana Lane.|
+-----------------------------+----------------------------+

   NB. The destroy code for a collection calls destroy for all objects in the collection. To avoid that, delete__ all of the objects from the collection first.
   destroy__addressbook ''
1

Definition

load jpath,'~user/classes/usn.ijs'
coclass 'collection'
coinsert 'usn'

obdelete =: 4 : 0
	isave =. items
	snsave =. sn
	i =. x delete_usn_ f. y       NB. delete from the list
	ob =. ( snsave i. i ) { isave NB. i is sn of deleted items
	destroy__ob ''
)

collect =: 3 : 0
	r =. ''
	for_i. items do.
		". 'r=.r,<' , y , '__i'
	end.
)

mcollect =: 4 : 0 "1
	r =. ''
	for_i. items do.
		". 'r=.r,<', x, '__i y'
	end.
)


dcollect =: 4 : 0 "1
	'l r' =. y
	r =. ''
	for_i. items do.
		". 'r=.r,< l', x, '__i r'
	end.
)

probe =: 4 : 0
	r =. ''
	for_i. i. x do.
		try. r =.  r , (": i), ' ', (". y , '_', (": i)  , '_') , CR catch. end.
	end.
)

destroy =: 3 : 0
	'destroy' mcollect '' NB. destroy all of objects in the list.
	codestroy ''
)

Unique Sequential Number (usn)

Example Usage

load jpath,'~user/classes/usn.ijs'
addresses =. '' conew 'usn'

NB. Method to add__ an item to the usn object. Output is a list of the usn's of the items that were inserted into the list and a list of the usn's of the items that were deleted.
   add__addresses <('Patrick';'3 Mill Road')
+-++
|0||
+-++
   NB. The items in the list.
   items__addresses
+---------------------+
|+-------+-----------+|
||Patrick|3 Mill Road||
|+-------+-----------+|
+---------------------+
  NB. The usn's of the items.
   sn__addresses
0

   NB. or...
   view__addresses ''
+-----+-----------------------+
|items|+---------------------+|
|     ||+-------+-----------+||
|     |||Patrick|3 Mill Road|||
|     ||+-------+-----------+||
|     |+---------------------+|
+-----+-----------------------+
|sn   |0                      |
+-----+-----------------------+

   NB. add__ another address
   add__addresses <('Bill';'1 Banana Lane')
+-++
|1||
+-++

   NB. Note that the items__ are in order.
   items__addresses
+--------------------+---------------------+
|+----+-------------+|+-------+-----------+|
||Bill|1 Banana Lane|||Patrick|3 Mill Road||
|+----+-------------+|+-------+-----------+|
+--------------------+---------------------+

   NB. Note that the usn's are in order of entry of the items.
   sn__addresses
1 0

   NB. If the same item is re-added then it is assigned the next usn. The output reports the usn of the item removed from the list in addition to the usn of the item added to the list.
   add__addresses <('Bill';'1 Banana Lane')
+-+-+
|2|1|
+-+-+
   items__addresses
+--------------------+---------------------+
|+----+-------------+|+-------+-----------+|
||Bill|1 Banana Lane|||Patrick|3 Mill Road||
|+----+-------------+|+-------+-----------+|
+--------------------+---------------------+
   sn__addresses
2 0

   NB. Items are deleted from the list in two ways.
   NB. 0&delete__ deletes the item specified.
   NB. 1&delete__ deletes the item with the usn specified.
   0&delete__addresses <('Bill';'1 Banana Lane')
2
   items__addresses
+---------------------+
|+-------+-----------+|
||Patrick|3 Mill Road||
|+-------+-----------+|
+---------------------+
   sn__addresses
0

   1&delete__addresses {. sn__addresses
0
   items__addresses

   sn__addresses


   add__addresses <('Bill';'1 Banana Lane')
+-++
|3||
+-++
   add__addresses <('Patrick';'3 Mill Road')
+-++
|4||
+-++
   items__addresses
+--------------------+---------------------+
|+----+-------------+|+-------+-----------+|
||Bill|1 Banana Lane|||Patrick|3 Mill Road||
|+----+-------------+|+-------+-----------+|
+--------------------+---------------------+
   sn__addresses
3 4

   NB. The todisk__ method stores the items to disk for retrieval by fromdisk__ .
   todisk__addresses jpath,'~temp/usnExamples.dat'

   NB. The destroy method outputs the usn of the destroyed items.
   destroy__addresses ''
3 4

   a =: '' conew 'usn'
   fromdisk__a jpath,'~temp/usnExamples.dat'
+--------------------------------------------+---+-+-+
|+--------------------+---------------------+|3 4|5|2|
||+----+-------------+|+-------+-----------+||   | | |
|||Bill|1 Banana Lane|||Patrick|3 Mill Road|||   | | |
||+----+-------------+|+-------+-----------+||   | | |
|+--------------------+---------------------+|   | | |
+--------------------------------------------+---+-+-+
   items__a
+--------------------+---------------------+
|+----+-------------+|+-------+-----------+|
||Bill|1 Banana Lane|||Patrick|3 Mill Road||
|+----+-------------+|+-------+-----------+|
+--------------------+---------------------+
   sn__a
3 4

   NB. The Number of items.
   ni__a
2
   NB. The Current Sequential Number (i.e. the next one)
   csn__a
5

   destroy__a ''
3 4

   NB. WHY ON EARTH DID I WRITE THIS?! Good question!
   NB.
   NB. Originally I wanted to store data for different time stamps in different files but needed to keep track of the file names as data is inserted and deleted.

   a =: '' conew 'usn'

   NB. Suppose there is some data d at t=3.
   add__a 3
+-++
|0||
+-++
   NB. The output indicates which usn was created, and that none were deleted, so I would put the data into a file with that number as a name.

   NB. The items property contains 3 which has sn 0 telling me that ts=3 data is in file number 0.
   view__a ''
+-----+-+
|items|3|
+-----+-+
|sn   |0|
+-----+-+

   NB. add__ some data at t=4
   add__a 4
+-++
|1||
+-++
   NB. The output indicates that usn 1 was created, and no usn were deleted, so I put the data into file number 1.
   NB. view__ shows that data for t=3 is in file 0 and data for t=4 is in t=1.
   view__a ''
+-----+---+
|items|3 4|
+-----+---+
|sn   |0 1|
+-----+---+

   NB. add__ data for t=2.
   add__a 2
+-++
|2||
+-++
   NB. The output tells me that the data should go into file number 3.
   NB. The sn are in order of when the items were added.
   view__a ''
+-----+-----+
|items|2 3 4|
+-----+-----+
|sn   |2 0 1|
+-----+-----+

   NB. Suppose t=3 data is to be modified.
   add__a 3
+-+-+
|3|0|
+-+-+
   NB. sn 4 was created, telling me the modified data should go in that file.
   NB. sn 0 was deleted so I should delete that file.
   NB. Note that the sn are still in order of items but a new sn for t=3 has been created. So if I want to run through the time series in order then I open the files in order of sn. I.e. 2, then 3, then 1.
   view__a ''
+-----+-----+
|items|2 3 4|
+-----+-----+
|sn   |2 3 1|
+-----+-----+

   NB. delete ts 2 from the list.
   0&delete__a 2
2
   NB. Output is the deleted sn, so I should delete the file labelled 2.
   view__a ''
+-----+---+
|items|3 4|
+-----+---+
|sn   |3 1|
+-----+---+

   NB. delete sn 1.
   1&delete__a 1
1
   view__a ''
+-----+-+
|items|3|
+-----+-+
|sn   |3|
+-----+-+

   NB. add__ mutliple ts...
   add__a i. 10
+-----------------------+-+
|4 5 6 7 8 9 10 11 12 13|3|
+-----------------------+-+
   view__a ''
+-----+-----------------------+
|items|0 1 2 3 4 5 6 7 8 9    |
+-----+-----------------------+
|sn   |4 5 6 7 8 9 10 11 12 13|
+-----+-----------------------+

   NB. Modify many ts...
   add__a 3 + i. 5
+--------------+-----------+
|14 15 16 17 18|7 8 9 10 11|
+--------------+-----------+
   NB. The output says which files to create and which to delete.
   view__a ''
+-----+--------------------------+
|items|0 1 2 3 4 5 6 7 8 9       |
+-----+--------------------------+
|sn   |4 5 6 14 15 16 17 18 12 13|
+-----+--------------------------+

   add__a 18 0 22
+--------+-+
|19 20 21|4|
+--------+-+
   view__a ''
+-----+---------------------------------+
|items|0 1 2 3 4 5 6 7 8 9 18 22        |
+-----+---------------------------------+
|sn   |20 5 6 14 15 16 17 18 12 13 19 21|
+-----+---------------------------------+

   NB. delete__ many ts.
   0&delete__a i.7
20 5 6 14 15 16 17
   view__a ''
+-----+--------------+
|items|7 8 9 18 22   |
+-----+--------------+
|sn   |18 12 13 19 21|
+-----+--------------+

   NB. destroy__ outputs all of the sn being destroyed so one knows which files are left on the disk.
   destroy__a ''
18 12 13 19 21

Definition

NB. Unique Sequential Numbers
load jpath,'~user/classes/utils.ijs'

coclass 'usn'
coinsert 'utils'

create=: 3 : 0
	sn =: 0$0 	NB. list of Serial Numbers
	csn =: 0  	NB. Current Serial Number (always increases)
	ni =: 0  	NB. Number of Items
	items =: 0$0 	NB. List of Items
)

destroy=: 3 : 0
	codestroy
	sn 		NB. output the destroyed Serial Numbers
)

add =: 3 : 0 "1
	sn =: sn , nsn =: csn + i. # y
	csn =: csn + # y
	items =: items {~ i =. /: items =: items, y
	ni =: ni + # y
 	sn =: i { sn
	try.
		RM =. 1&delete sn -. sn {~ items i: ~.items
	catch.
		throw.
	end.
	nsn;RM
)

delete =: 4 : 0 "1
	if. ( 0 < #y ) *. 0 < #sn do.
		if. 0 = x do.
			NB. delete by items
			try.
				i =. sn {~ items i."1 0 y 	NB. sn of the items for deletion
			catch.	
				type_jthrow_ =: 'No such items'
				throw.
			end.
		else.
			i =. y
		end.
		NB. make sure all the sn exist
		if. -. 0 e. i e. sn do.
			j =. sn i."1 0 i NB. indices in sn and items to remove
			keep =. j -.~ i. ni
			items =:keep { items
			sn =:keep { sn
			ni =: #items
			i	
		else.
			type_jthrow_ =: 'No such sn'
			throw.
		end.
	end.
)

view =: 3 : 0
	('items';'sn'),. items;sn
)

fromdisk =: 3 : 0
	'items sn csn ni' =: diskio y
)

todisk =: 3 : 0
	 (items;sn;csn;ni) diskio y
)

utils.ijs

The contents of the utils.ijs file referred to by usn.ijs.

coclass 'utils'
exists 	=: 0&<@#@(1!:0)@<			NB. does file or directory y exist
newdir 	=: 1!:5@< 				NB. create new directory y	
makepath =: ( _1 }. [: ; ('/',~])&.> ) "1 	NB. create a path string from boxed parts
typecheck =: =3!:0				NB. check if y is of these types
isboxed =: 32&typecheck
isfloat =: 8&typecheck
isliteral =: 2&typecheck
diskio =: ((3!:2)@(1!:1))@< : ((3!:1)@[ (1!:2) <@]) "_ 1 NB. read and write to disk