Multiple distinct objects

From Rosetta Code
Revision as of 00:41, 29 January 2009 by rosettacode>Kevin Reid (new task (inspired by the *name* of "Create a Sequence of unique elements"))
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Task
Multiple distinct objects
You are encouraged to solve this task according to the task description, using any language you may know.

Create a sequence (array, list, whatever) consisting of n distinct items of the same type. n should be determined at runtime.

By distinct we mean that if they are mutable, changes to one do not affect all others; if there is an appropriate equality operator they are considered unequal; etc. The code need not specify a particular kind of distinction, but do not use e.g. a numeric-range generator which does not generalize.

This task was inspired by the common error of intending to do this, but instead creating a sequence of nreferences to the same mutable object; it might be informative to show the way to do that as well.

This task mostly makes sense for languages operating in the pass-references-by-value style (most object-oriented or 'dynamic' languages).

C

foo *foos = malloc(n * sizeof(*foos));
for (int i = 0; i < n; i++)
  init_foo(&foos[i]);

(Or if no particular initialization is needed, skip that part, or use calloc.)

Common Lisp

The mistake is often written as one of these:

(make-list n :initial-element (make-the-distinct-thing))
(make-array n :initial-element (make-the-distinct-thing))

which are incorrect since (make-the-distinct-thing) is only evaluated once. A common correct version is:

(loop repeat n collect (make-the-distinct-thing))

which evaluates (make-the-distinct-thing) n times and collects each result in a list.

Haskell

If the creator of the distinct thing is in some monad, then one can write

replicateM n makeTheDistinctThing

in an appropriate do block. If it is distinguished by, say, a numeric label, one could write

map makeTheDistinctThing [1..n]