Multiple distinct objects

From Rosetta Code
Revision as of 16:29, 29 January 2009 by rosettacode>Mwn3d (Added Java, changed some code tags to tt tags)
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]

Java

Works with: Java version 1.5+

It's not pretty but it gets the job done. The first method here is the one that does the work. The second method is a convenience method so that you can pass in a String of the class name. public static LinkedList<Object> getNNewObjects(int n, Class c){ LinkedList<Object> ans = new LinkedList<Object>(); try { for(int i=0;i<n;i++) ans.add(c.newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return ans; }

public static LinkedList<Object> getNNewObjects(int n, String className) throws ClassNotFoundException{ return getNNewObjects(n, Class.forName(className)); }

Python

The mistake is often written as: [Foo()] * n # here Foo() can be any expression that returns a new object which is incorrect since Foo() is only evaluated once. A common correct version is: [Foo() for i in xrange(n)] which evaluates Foo() n times and collects each result in a list. This last form is also discussed here, on the correct construction of a two dimensional array.

Ruby

The mistake is often written as one of these: [Foo.new] * n # here Foo.new can be any expression that returns a new object Array.new(n, Foo.new) which are incorrect since Foo.new is only evaluated once. A common correct version is: Array.new(n) { Foo.new } which evaluates Foo.new n times and collects each result in an Array. This last form is also discussed here, on the correct construction of a two dimensional array.