From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14488 invoked from network); 24 Jul 2005 10:32:39 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 24 Jul 2005 10:32:39 -0000 Received: (qmail 77851 invoked from network); 24 Jul 2005 10:32:31 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 24 Jul 2005 10:32:31 -0000 Received: (qmail 11348 invoked by alias); 24 Jul 2005 10:32:24 -0000 Mailing-List: contact zsh-users-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 9145 Received: (qmail 11339 invoked from network); 24 Jul 2005 10:32:24 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 24 Jul 2005 10:32:24 -0000 Received: (qmail 76831 invoked from network); 24 Jul 2005 10:32:24 -0000 Received: from vms048pub.verizon.net (206.46.252.48) by a.mx.sunsite.dk with SMTP; 24 Jul 2005 10:32:20 -0000 Received: from candle.brasslantern.com ([71.116.88.149]) by vms048.mailsrvcs.net (Sun Java System Messaging Server 6.2 HotFix 0.04 (built Dec 24 2004)) with ESMTPA id <0IK40067GNXQR065@vms048.mailsrvcs.net> for zsh-users@sunsite.dk; Sun, 24 Jul 2005 05:32:16 -0500 (CDT) Received: from candle.brasslantern.com (IDENT:schaefer@localhost [127.0.0.1]) by candle.brasslantern.com (8.12.11/8.12.11) with ESMTP id j6OAWEup020782 for ; Sun, 24 Jul 2005 03:32:14 -0700 Received: (from schaefer@localhost) by candle.brasslantern.com (8.12.11/8.12.11/Submit) id j6OAWEka020781 for zsh-users@sunsite.dk; Sun, 24 Jul 2005 03:32:14 -0700 Date: Sun, 24 Jul 2005 10:32:13 +0000 From: Bart Schaefer Subject: Re: Sorting file names randomly In-reply-to: <20050724073914.GA2665@DervishD> In-reply-to: <20050724083732.GA73@DervishD> In-reply-to: <20050724084014.GA86@DervishD> To: Zsh Users Message-id: <1050724103213.ZM20780@candle.brasslantern.com> MIME-version: 1.0 X-Mailer: Z-Mail (5.0.0 30July97) Content-type: text/plain; charset=us-ascii References: <20050723194240.GA32416@DervishD> <20050723212657.GA744@DervishD> <1050724064415.ZM20425@candle.brasslantern.com> <20050724073914.GA2665@DervishD> <20050724083732.GA73@DervishD> <20050724084014.GA86@DervishD> Comments: In reply to DervishD "Re: Sorting file names randomly" (Jul 24, 9:39am) Comments: In reply to DervishD "Re: Sorting file names randomly" (Jul 24, 10:37am) Comments: In reply to DervishD "Re: Sorting file names randomly" (Jul 24, 10:40am) X-Spam-Checker-Version: SpamAssassin 3.0.4 (2005-06-05) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.3 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.0.4 On Jul 24, 9:39am, DervishD wrote: } } > for ((i=1; i <= $#; ++i)) { reply[i*RANDOM/32768+1]+=($argv[i]) } } } Why is it better than my function? It's shorter (which is one of the things you asked for), and it only does array processing rather than building up and tearing down strings. } Maybe this is faster than doing the '(e' thing? More on this below. } > for ((i=1; i <= $#; ++i)) { h[$i.$RANDOM]=$argv[i] } } } I understand this one better ;) That's another solution I thought } of, but I assumed that if I used associative arrays, the order of } elements would be the order in which they were inserted (which is } not, I've discovered right now). } } Anyway, the ordering of elements in an associative array is not } very random if $RANDOM is not included in the key, and I don't } understand it :?? How are associative arrays elements sorted? Are you familiar with the concept of hash tables? That's how nearly all languages that have associative arrays, implement them, and in many cases (e.g. Perl) they're even called "hashes" by the language. You can think of the elements as being ordered by a set of numbers computed by applying a simple algorithm to the ascii values of the characters in the key strings. It's actually a bit more complex than that, but close enough. On Jul 24, 10:37am, DervishD wrote: } } How about this?: Well ... } function shuffle () { } } setopt nullglob globdots rcexpandparam } } reply=() } reply=($*) Don't you mean $~* there? Otherwise you have the problem with multiple directories that you alluded to once before. } reply=($reply(e:'REPLY="${(l.5..0.)RANDOM} $REPLY"':)) This is wasteful in a number of ways. First, the (l.5..0.) is just left-zero-padding $RANDOM, so rather than force the shell parse that and work out what to do once for every file name, it would be better to declare "local +h -Z 5 RANDOM" as I did. (Just remember to seed RANDOM when making it local.) Second, by using a glob qualifier, you're forcing the shell to stat() every file name second time, after it has already been done once when reply=($~*) is assigned [assuming $~* is what you meant]. Third, you're doing string concatenation, adding six bytes for each file name. If you're worried about exceeding argument limits, you ought to be worried about how much extra memory that eats. Fourth, you've eventually got to do this ... } reply=(${reply/#????? /}) ... which has to copy every string in order to pattern-match it and chop it up before assigning it back again, so you're roughly doubling the memory needed right there, possibly as much as tripling it if I recall correctly how array assignments are performed. My hash solution isn't very much less memory intensive (if you skipped the final assignment to the reply array and just printed the values it would be better); but the += version is about as small a footprint as you're going to get, because inserting array slices only copies the new elements being inserted (everything else is moving of pointers to the existing elements). } print -l $reply } } return 0 Unless you expect "print" to fail, the "return 0" is redundant. } It does the globbing outside, and shuffles correctly. Any way of } making the 'reply' assignments shorter? You can eliminate the glob qualifier by using the "eval" trick I posted on a different thread (placement of quotes and spaces is important): eval 'reply=(' '$RANDOM '${(q)reply} ')' However, you can't do fewer than three assignments. On Jul 24, 10:40am, DervishD wrote: } } > reply=($*) } > reply=($reply(e:'REPLY="${(l.5..0.)RANDOM} $REPLY"':)) } > reply=(${(o)reply}) } } How could I avoid doing this? I cannot put the 'o' in the } assignment above this one because it doesn't work, it seems to sort } *before* applying the 'e' glob modifier). Obviously the glob applies after any sorting in that second assignment. The glob qualifier is being applied to the strings that *result* from the parameter expansion; that's why you need the rcexpandparam option.