From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: zsh-users-return-23721-ml=inbox.vuxu.org@zsh.org X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from primenet.com.au (ns1.primenet.com.au [203.24.36.2]) by inbox.vuxu.org (OpenSMTPD) with ESMTP id f0e5dc48 for ; Thu, 25 Oct 2018 19:42:51 +0000 (UTC) Received: (qmail 16335 invoked by alias); 25 Oct 2018 19:42:35 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: List-Unsubscribe: X-Seq: 23721 Received: (qmail 27437 invoked by uid 1010); 25 Oct 2018 19:42:35 -0000 X-Qmail-Scanner-Diagnostics: from out3-smtp.messagingengine.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1. Clear:RC:0(66.111.4.27):SA:0(-2.6/5.0):. Processed in 6.385805 secs); 25 Oct 2018 19:42:35 -0000 X-Envelope-From: d.s@daniel.shahaf.name X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= daniel.shahaf.name; h=message-id:from:to:cc:mime-version :content-transfer-encoding:content-type:references:in-reply-to :date:subject; s=fm1; bh=rL7rMCo8cCuxXIQT6zQIo+vibhBwLZUpIL5E+kg 4rfM=; b=AU2sNI48TseYAihFKx/c+qHgVpBLkpFFbQwPjJAfGfTGDOFLuhHrfa4 cBVZ08AgN1WN8vSXlVLinsaspH/CGhPHU61HyryilkLmzeadQKo+v+g/sdPpiUgA CtN5H2xQE5hKU/of8g75z6FSQ/Jj/fBLljQdDQCUZ/LjuyjrtKwjNKIjFkhHcjBi 6PchqUNRTce7TMYGpoA++uyWEI7FF9M3TsgzD86UGOGLmQAOAMSp2fkR0YfdPwaG QHG7rFCrD1VRqmo6/RLoCfdro6h3Q5H7EJukSl/K1vkcZaMxQbJy0ILQSzAu+ZgR H+NJNv5/8awfhMRc4t8eVGAPqjile2g== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm1; bh=rL7rMCo8cCuxXIQT6zQIo+vibhBwLZUpIL5E+kg4r fM=; b=B0FruwyO3rmfV3cPxncFObuqoI6YdbJ96DYrn6HtcOozeJgUnsZFCtIjc vKXUd9D40az0HIiq+/bqRp/uk9NsRGN49kejCqoJYWqeRjvjFH7OvEunaAqVgYW+ FNn55/xt4X1IzJAuHPA1jCIU5S52bRXyp9K+dtmk+8Vg6brJDxFJhZdTm2BWlh+h u0Hf2oHilNTeFLjkI2gFyE79RgZVpjhF1V0BCMduItCT/lqTVLQ2R3eYCETcZmOZ LfSVD0ECBeAJLl9H5XE9bgHsg5bBXI/uoOWMKj2Ss86zOpWQTviHZRwN+sPUcnlv Z2ks4d7Q6mvevNw+Dx+CYpnjbg9AA== X-ME-Sender: X-ME-Proxy: Message-Id: <1540496542.2435852.1554725120.69463593@webmail.messagingengine.com> From: Daniel Shahaf To: =?utf-8?Q?Jesper=20Nyg=C3=A5rds?= Cc: Zsh Users MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" X-Mailer: MessagingEngine.com Webmail Interface - ajax-63008d4f References: In-Reply-To: Date: Thu, 25 Oct 2018 19:42:22 +0000 Subject: Re: Filtering array on index Mikael Magnusson wrote on Thu, 25 Oct 2018 20:17 +0200: > On 10/25/18, Jesper Nyg=C3=A5rds wrote: > > I have an array which is the result of using zparseopts on a specificat= ion > > that makes it possible to specify several filters with a -v flag. The > > resulting array might look like the following: > > > > myarr=3D(-v filter1 -v filter2) > > > > I want to get rid of the "-v" elements, but only when they are the flag, > > and not the argument. In other words, I would the like the array (-v > > filter1 -v -v) to result in (filter1 -v). > > > > I had previously used: > > > > ${myarr:#-v}} > > > > which worked well, as I could accept the fact that -v was not possible = to > > use as the option argument. > > > > However, now I need to make sure that a -v argument is preserved, and I > > thus need a compact way of specifying that I want to keep every other > > element in the array. > > > > The most compact way I have found is: > > for dash arg in $myarr; do myarr[(r)$dash]=3D() > > > > This works, but I was wondering if there's some more elegant solution, > > preferrably without using iteration? >=20 > The above example doesn't work if you need to preserve the order (it > will just remove the first $dash it finds). >=20 > % a=3D(-v filter1 -v -v -v middle -v -v -v final) > % for dash arg in $a; do a[(r)$dash]=3D(); done; pl $a > filter1 > middle > -v > -v > final >=20 > middle "should" be between the two remaining -v. >=20 > This works, but is still a loop obviously: > % for i in {$(($#a/2))..1}; do a[i*2-1]=3D(); done; pl $a > filter1 > -v > middle > -v > final >=20 > (Note that it is necessary to iterate backwards as the indices will > change otherwise) Another option: myarr=3D(-v filter1 -v filter2) () { local i j; myarr=3D(); for i j; do myarr+=3D($j) ; done } "${myarr[@]}" In zparseopts context we can probably assume the arguments to the -v option don't contain literal NUL bytes, so perhaps something like this: % myarr=3D( -v 'foo foo' -v 'bar bar' -v '' ) % printf -v x '\0k1%s\0k2%s\0v' "$myarr[@]" % x=3D${x//$'\0k1-v\0k2'} % x=3D${x%$'\0v'} % () { typeset -p argv } "${(@ps.\0v.)x}" typeset -g -a argv=3D( 'foo foo' 'bar bar' '' ) %=20 Is there a way to do this in O(N) time? (The array-based solutions are quadratic complexity due to indexing/appending being O(N). I'm not sure about the printf.) Cheers, Daniel