What about?

   20 timesCollect: [ 100 atRandom ] as: OrderedCollection

It could use cull: to accept the :index argument, or not.

It does seem that this (1 to: n) collect: [ :n| ...] has come up several times over the years, but not always in the context of instantiating a collection.

Let's take a side-by-side look:
OrderedCollection new: 20 filledWith: [100 atRandom].
           20 timesCollect: [ 100 atRandom ] as: OrderedCollection

Hmm.  Although the number of words and elements seems about the same, the order is different because the receiver is different.  Even though I like the flexibility of #timesCollect:as: over #new:filledWith:, and also how it echoes #collect:as:, object construction is typically the responsibility of Classes, so, idiomatically, I think #new:filledWith: probably WOULD be found afterall (even if not by me because of my habits).  I retract my -1.

I do still like #timesCollect: for those other cases though, since it saves from needing to allocate the (1 to: n) Interval.  Hm.

Best,
  Chris


On Wed, Nov 20, 2019 at 1:48 AM Marcel Taeumel <marcel.taeumel@hpi.de> wrote:
Hi, all.

What's the "most idiomatic" way to create an array with 100 random numbers > 0 < 100?

(1 to: 100) collect: [:ea | 100 atRandom]
Array streamContents: [:s | 100 timesRepeat: [s nextPut: 100 atRandom]].
...

Best,
Marcel

Am 20.11.2019 07:08:34 schrieb Chris Muller <asqueaker@gmail.com>:

On Tue, Nov 19, 2019 at 10:58 PM Chris Muller <asqueaker@gmail.com> wrote:
They share the same selector API, but for ArrayedCollection's, it culls integers 1 to: n, while for non-Arrayed, it culls nil over and over.

Woops, I got that wrong, sorry.  It is the index in both cases, not nil. That's better but, still, I'm sure I would just write collect:as: without remembering this.

 - Chris

 
  This means the sender will have to know whether it's Arrayed or not anyway (otherwise you'd need a nil check inside the loop).  And so, if you have to know that, one could just write classic Smalltalk.

   (1 to: 20) collect: [ :i | ... ]

(with or without an "as:" converter on the end).

OTOH, if you were expecting a non-arrayed collection, then simply:

    Array streamContents: [ : stream | ... ] 

I do appreciate the readability for people less experienced with Smalltalk, but for the long run, classic, readable, portable Smalltalk may actually be the better way for them to read it.

Collecting nil over and over could be a sign of something not fully optimized here.

-1 on this one, even though I'm really enjoying many of your other contributions, Christoph.

Best,
  Chris

On Fri, Sep 6, 2019 at 9:57 AM <commits@source.squeak.org> wrote:
A new version of Collections was added to project The Inbox:
http://source.squeak.org/inbox/Collections-mt.852.mcz

==================== Summary ====================

Name: Collections-mt.852
Author: mt
Time: 6 September 2019, 4:57:45.245608 pm
UUID: 3582be1c-a006-ed46-a517-3d2d570db6cc
Ancestors: Collections-mt.851

Proposal: Initialize a new collection with a computation block without needing an existing collection to #collect: from.

OrderedCollection new: 20 filledWith: [100 atRandom].

Thanks to Christoph (ct) for the idea.

If we want this in Trunk, there will be tests. :-)

=============== Diff against Collections-mt.851 ===============

Item was added:
+ ----- Method: ArrayedCollection class>>new:filledWith: (in category 'instance creation') -----
+ new: size filledWith: aBlock
+       "Similar to #collect:as: and #fillFrom:with: but uses only the interval (1 to: size) to fill the collection. Different compared to #new:withAll: because aBlock can return different values for each index."
+
+       | result |
+       result := self new: size.
+       1 to: size do: [:each | result at: each put: (aBlock cull: each)].
+       ^ result!

Item was added:
+ ----- Method: Collection class>>new:filledWith: (in category 'instance creation') -----
+ new: size filledWith: aBlock
+       "Similar to #collect:as: and #fillFrom:with: but uses only the interval (1 to: size) to fill the collection. Different compared to #new:withAll: because aBlock can return different values for each index."
+
+       | result |
+       result := self new: size.
+       1 to: size do: [:each | result add: (aBlock cull: each)].
+       ^ result!