Question - Projecting a collection onto a larger collection

Richard A. O'Keefe ok at cs.otago.ac.nz
Mon Jun 23 00:52:45 UTC 2003


"Brent Pinkney" <pinkney_b at aircom.co.za> asked:
	What is the preffered (sic.) method of porjecting (sic.)
        on collection onto a larger collection ? 
	
"Project" is a rather odd name for the operation; projection is
normally taken as mapping from one space to another space of
the same or *lower* dimension.

	collect:, select:  and reject only map a collection onto a
	smaller collection.
	
or the same size.

	e.g. I want to map {Date.  Time } to
	{ Date.  Date class.  Time.  Time class }
	
	I dimly remember seeing some mention of a project: method
	
Use the method finder.  All the methods I can find with "project"
in them seem to be about PROjects not about proJECTing.

	I am looking for Something of the flavour:
	
		{Date. Time } project: [ :nc :e | nc add: e; add: e class ].
	
It looks as though you want the Common Lisp #'mapcan function.

In a 10 minute scan I couldn't find or recall anything that's exactly
what you want.  However, you could add a method to SequenceableCollection:

    class SequenceableCollection
    category 'converting'

    concenation
	|result index|
	
	result := Array new: (
	    self inject: 0 into: [:sum :each | sum + each size]).
	index := 0.
	self do: [:each |
	    each do: [:item |
	        result at: (index := index + 1) put: item]]
        ^result

Then you could write
    ({Date. Time} collect: [:each | {each. each class}]) concatenation

Why didn't I use #replaceFrom:to:with: in #concatenation?
So that the method would work with a sequence of collections of
any type, not just a sequence of sequences.  It's a conversion
method, after all, and binding the elements of an element to an
essentially arbitrary order is no more than #asArray does.

Given a collection of size N where the size of the result is going to
be M, this requires a peak of O(N+M) space for a final result of O(M)
space.  To do better, we'd have to have a method which fused the
effects of #collect: and #concatenation in one, but then we would not
be able to use #concatenation with #select: or #with:collect: or in
any other way.



More information about the Squeak-dev mailing list