The Artima Developer Community
Sponsored Link

Agile Buzz Forum
Let's Lookup another Collection of Extensions

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
James Robertson

Posts: 29924
Nickname: jarober61
Registered: Jun, 2003

David Buck, Smalltalker at large
Let's Lookup another Collection of Extensions Posted: Jun 12, 2004 8:10 PM
Reply to this message Reply

This post originated from an RSS feed registered with Agile Buzz by James Robertson.
Original Post: Let's Lookup another Collection of Extensions
Feed Title: Travis Griggs - Blog
Feed URL: http://www.cincomsmalltalk.com/rssBlog/travis-rss.xml
Feed Description: This TAG Line is Extra
Latest Agile Buzz Posts
Latest Agile Buzz Posts by James Robertson
Latest Posts From Travis Griggs - Blog

Advertisement
Thursday's blog a little late here. Playing catchup.

One day, a while back, I had put together a "model" of some real world phenomena that I was pasting a UI on top of. Part of it was a pretty simple thing where an Array did the model well. There was a bit of code where the index of the elements was important too.

Then they pulled a fast one on me: "sometimes, it's possible for one of the intermediate slots to just not be there." I sighed. Noodled for a little bit. And then decided to just use a Dictionary with Integer lookup keys. Doing so was kind of enlightening; I suddenly thought about the problem with a higher level of APIs, things like keysAndValuesDo:, etc. At this point, it donned on me that SequenceableCollections (or Sequences for short) are just Dictionaries with specialized key domains. Adding a variety of the dictionary APIs to Sequence enables more mental tools to use on your model. And that's one of the things Smalltalk is all about: giving you the programmer better tools to bridge the way your brain wants to model problems with the way the computer does. The following methods (and tests) should be self explanatory, because they all come from Dictionary.

The Essential Methods

at: anIndex ifAbsent: aBlock 
	^[self at: anIndex] on: SubscriptOutOfBoundsError do: [:ex | aBlock value]

keys
	^1 to: self size

Methods that are easy after that

associationsDo: aBlock 
	self keysAndValuesDo: [:key :val | aBlock value: key -> val]

includesKey: aNumber 
	^self keys includes: aNumber

keysDo: aBlock 
	self keys do: [:i | aBlock value: i]

at: aKey ifPresent: aBlock 
	| val |
	val := self at: aKey ifAbsent: [^nil].
	^aBlock value: val

Honorable Mention

keysAndValuesDo: aBlock  
	"Evaluate aBlock with each of the receiver's key/value pairs
	(e.g. indexes and elements) as the arguments."

	1 to: self size do: [:i | aBlock value: i value: (self at: i)]

Wait a minute, that's not an extension! That's in the base! Well it is since 7.0. I submitted it then; it was the original inspirator for the rest of these. I wish that it's siblings would make it into the base as well.

The Tests

testGenericAtIfAbsent
	| a |
	a := (11 to: 20) asArray reverse.
	self
		assert: (a at: 3 ifAbsent: [#hi]) = 18;
		assert: (a at: -1 ifAbsent: [#hi]) = #hi;
		assert: (a at: 20 ifAbsent: [#hi]) = #hi

testGenericAssociationsDo
	| coll keys values |
	coll := Array 
				with: 'abc'
				with: 'xyz'
				with: 'ijk'.
	keys := OrderedCollection new.
	values := OrderedCollection new.
	coll associationsDo: 
			[:assoc | 
			keys addLast: assoc key.
			values addLast: assoc value].
	self
		sequence: values sameAs: #('abc' 'xyz' 'ijk');
		sequence: keys sameAs: (1 to: 3)

testGenericIncludesKey
	self
		assert: ((OrderedCollection with: 5 with: 3) includesKey: 2);
		deny: ((Array new: 5) includesKey: 6);
		deny: ((List new: 1) includesKey: 0)

testAtIfPresent
	| val |
	val := nil.
	#(2) at: 1 ifPresent: [:each | val := 2].
	self assert: val = 2.
	#(2) at: 2 ifPresent: [:each | val := 0].
	self deny: val = 0.
	((Dictionary new)
		at: 4 put: 5;
		at: 6 put: 7;
		yourself) at: 6 ifPresent: [:each | val := each].
	self assert: val = 7.
	((Dictionary new)
		at: 4 put: 5;
		at: 6 put: 7;
		yourself) at: 8 ifPresent: [:each | val := nil].
	self deny: val isNil

Read: Let's Lookup another Collection of Extensions

Topic: What is WithStyle? Previous Topic   Next Topic Topic: WithStyle Developers Program

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use