From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.0 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,HTML_MESSAGE,HTML_OBFUSCATE_05_10, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 Received: from zero.zsh.org (zero.zsh.org [IPv6:2a02:898:31:0:48:4558:7a:7368]) by inbox.vuxu.org (Postfix) with ESMTP id 90012240B4 for ; Fri, 19 Jan 2024 16:48:34 +0100 (CET) ARC-Seal: i=1; cv=none; a=rsa-sha256; d=zsh.org; s=rsa-20210803; t=1705679314; b=o95vSu9EowPOTZfI2K134HheSgqo7pPc+makmkk3xcQT5JnbWJm761/n9MlKVw86KdB/iKWUyc SWPdfupaIYWX7jJTFZjDgaEWvbEmCcQKTVZmlXh9see+UuE+dVanDEUNJRQUBxDXfF+dpCq4ZW N+74I68C9bQDBsFXFS4RfuY/GrqnLhARLXc+te4Zkam3SMUVQWEgM8YdgeZ4lsVG7+q9/opNCO P+BgqPTwSop/v4HbTZfj9hpoCt0LFN9GqubcSuMp437mo6DsihGUySE0AZf0Ksuy/l4u+OJqqQ E9qObGU646dlhjyjDzVb8r2EctW2RfSjj17TFKqG/iujDg==; ARC-Authentication-Results: i=1; zsh.org; iprev=pass (mail-lj1-f180.google.com) smtp.remote-ip=209.85.208.180; dkim=pass header.d=gmail.com header.s=20230601 header.a=rsa-sha256; dmarc=pass header.from=gmail.com; arc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed; d=zsh.org; s=rsa-20210803; t=1705679314; bh=zMoiYX/3pM/7Xej2a1GOWzFjOwZGkLzf8dFiO+x+rzw=; h=List-Archive:List-Owner:List-Post:List-Unsubscribe:List-Subscribe:List-Help: List-Id:Sender:Content-Type:To:Subject:Message-ID:Date:From:In-Reply-To: References:MIME-Version:DKIM-Signature:DKIM-Signature; b=osL+jx/r9xvbxHV24S/VX+BbYPfbtg/2Hjxa336OBfIZnrlWBqpLcJCufm0m/DhcE07S/59y7v NhE8AegcjEd9DkDqJoLmbjrXuP7v3kEWWGSc7yubdnw+VXk5Mg2C9BMgZaMpS0Uj4O3qY/x6vP oEERaPylub6o890R7GBvwdQdoQY5pXKiwyV5TWSKEHw99IUd78gHExBFlDgYXgoQVUUcqeDCFd hR81XJtT+lwPcugZp9B3bj54hkLYPzdmHx8xghu+3x73zo7LEmbFaFimjkbt1dyI3EpQH2KVpK UbglWvnYNQnHAJ2ZKXQiuImZvYdEHGtFh3n076qKMFggGQ==; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=zsh.org; s=rsa-20210803; h=List-Archive:List-Owner:List-Post:List-Unsubscribe: List-Subscribe:List-Help:List-Id:Sender:Content-Type:To:Subject:Message-ID: Date:From:In-Reply-To:References:MIME-Version:Reply-To:Cc: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID; bh=x3+anGwIITiA2pefgQTkMeAQXfO48Gl2SYd78KKvsB0=; b=kf3ZA0y5PHxvgQHB0fo/PiOZvE 4upu7vffbMB2U0+Q73jzumyebzGEqY6kppmL3Ji+QikfiskfHOqXXHOjqdtMgDlE5CEMIGrdv1PM4 Z0Z1LcOjOm/VzcmqdjRfhCeiCrnYZ7TNUNa/PpOqR9XBixhvEqy2UAFoDmC+kbPn+Xjz7LOzvWTOl KrvZvYkfNHAQItjRG+KqUQUTDjSj1LDUAr1JXLYZiYx0CDvLZZJPcysGxibqTw7dnQFgcc2pufMJz wmzdL2SYQblvnAzqLYPUmxR5WNO+/CgoiGXCi5AiVTE43kAz8uw/x0FE/ENEhz8bdGqoxw9fYIgCG J1wWcZRQ==; Received: by zero.zsh.org with local id 1rQr6f-0004Yw-UG; Fri, 19 Jan 2024 15:48:33 +0000 Authentication-Results: zsh.org; iprev=pass (mail-lj1-f180.google.com) smtp.remote-ip=209.85.208.180; dkim=pass header.d=gmail.com header.s=20230601 header.a=rsa-sha256; dmarc=pass header.from=gmail.com; arc=none Received: from mail-lj1-f180.google.com ([209.85.208.180]:42452) by zero.zsh.org with esmtps (TLS1.3:TLS_AES_128_GCM_SHA256:128) id 1rQr5T-0003sq-Nb; Fri, 19 Jan 2024 15:47:22 +0000 Received: by mail-lj1-f180.google.com with SMTP id 38308e7fff4ca-2cdeb808f28so9306761fa.1 for ; Fri, 19 Jan 2024 07:47:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1705679238; x=1706284038; darn=zsh.org; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=x3+anGwIITiA2pefgQTkMeAQXfO48Gl2SYd78KKvsB0=; b=L8L6XMcigr1IJd4z0Ac5iq8HK2a0MbJz5D5/LQe1f8++/r2NhIEXWzJ3yP1sxC1rac MVRYvGYCZjqYyONqVa043rqFg3YHweS8jHpijG+pWy7FDpdUWB+uJwF1KHNqOhsRFghe s0jlq1WOHKkHDSoQGDyDXf3p6bL229DsvosrAgSeFzJWni3ACy4RWlr1Qj38YKR5cpJI oAvXRaUDyrVX9agPqZplkq68R4p4H4aDsIQHv/f57Sn16goybaqYekuv/q/zA3ZMhnWR KoTOT86mi3L00+1Z5Z3knWiJ1eTdbHchTqXVpBLIcfFluLtC8KTr/uErHyLhM/zLEA8q g+nA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1705679238; x=1706284038; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=x3+anGwIITiA2pefgQTkMeAQXfO48Gl2SYd78KKvsB0=; b=P3C0DPv52Qh1OSlxErF4wQCYL38XdVDiW8pGqJaGyk0GzPjwBbCzq4KYMHN+cXxgBc H93xN3zZNW9kcNbn4TcmfPDslKQHPYvL4htnY62DrIg+LM+CiVjqpsgpHigZrPbjSQjd hZP3UxZH3Fipy2PLUKH6kYGNMawF4/d4ykXZ30Mx4q2U9sB9JwOdhyk9rYQ5vB7EUfI7 SWVEyq7IEfIQRERLIDg9PRSfXBguw/8wYE/AkW3Ue5aLzW9vLcEaS9uGMX9mawYSYPRk ti522pYnmIMwarVpaRu3FM2v3ZdyUyxF+cIReLzRq7epAzaZqqgkzi/e84lvkmdfSIkU p+vg== X-Gm-Message-State: AOJu0Yzg4OBmh7QvV+Di+nBU/38kVSrDJWpwzKANuoUS+kWuydzaI8dV 06i2pDa5rgWGF295NX6pFVqPbxOfpmRE3ZdiRDgYU1ZxXsvnbS61MTpyIF5Dium2mgxxps+s708 0hm0PSMJGipzID5u3O7376tjDyVcKeHQhv6I= X-Google-Smtp-Source: AGHT+IGkteUGuoo2QOSS9i59xl/qwNkjqIw8MTARiV3yVP7hkqaf3ZFrwQjYPLagTzKxOs9LYS6l2sT+Cif3KreBf8c= X-Received: by 2002:a2e:988e:0:b0:2cd:f82b:9091 with SMTP id b14-20020a2e988e000000b002cdf82b9091mr790429ljj.3.1705679237706; Fri, 19 Jan 2024 07:47:17 -0800 (PST) MIME-Version: 1.0 References: <7b20b425-59b2-466d-a9aa-a2768d1d4633@app.fastmail.com> <4b475319-ef78-4d46-a62c-27c3b0af3ea4@eastlink.ca> <49702cd2-814c-4461-9819-cc2b85bd3ea2@eastlink.ca> <50941e8e-86e2-4e89-8644-c863f846e805@eastlink.ca> <20240119102755.5ma5psbccsuo5ohj@chazelas.org> In-Reply-To: From: "Mark J. Reed" Date: Fri, 19 Jan 2024 10:46:58 -0500 Message-ID: Subject: Re: Empty element elision and associative arrays (was Re: Slurping a file) To: zsh-users@zsh.org Content-Type: multipart/alternative; boundary="00000000000010766e060f4e65de" X-Seq: 29525 Archived-At: X-Loop: zsh-users@zsh.org Errors-To: zsh-users-owner@zsh.org Precedence: list Precedence: bulk Sender: zsh-users-request@zsh.org X-no-archive: yes List-Id: List-Help: , List-Subscribe: , List-Unsubscribe: , List-Post: List-Owner: List-Archive: --00000000000010766e060f4e65de Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Fri, Jan 19, 2024 at 9:58=E2=80=AFAM Ray Andrews wrote: > So it seems that zsh already does intend the ability to output the array > in a declared way as Stephane showed (hash tables notwithstanding). Thus > it's simply a matter of making that work as it proposes to do. Couldn't > ask for more. > Well, let's be clear about what's happening. As a general rule, associative arrays, as implementations of the abstract data type known as Map or Table, are fundamentally unordered, regardless of the implementation details. It's true that some implementations naturally keep the keys in a recognizable order (e.g. binary trees in lexical order by key, association lists in insertion order), while others (such as hash tables) do not, but such details don't necessarily dictate the features of any given implementation. Most systems with associative arrays don't provide a mechanism to retrieve the elements in a specified order. Some do =E2=80=93 Ksh93+ was brought up,= and I mentioned JavaScript, PHP, Python, and Ruby. Sometimes this is an actual feature and other times an accidental detail; in Clojure, maps that are small enough (less than about eight pairs) are stored using a data structure that keeps the keys in lexical order, so you might be lulled into thinking that's true generally, but larger maps use a hash table and revert to a seemingly unordered state. Zsh has expansion flags that let you get *either* the keys ( *k* ) or the values in lexical order, ascending ( *o *) or descending ( *O* ). Unfortunately it does not have a way to get the keys and values simultaneously in any sort of meaningful order while maintaining the pairwise association. If you use both flags *k *and *v* together with either *o *or *O*, you will get an undistinguished muddle of keys and values all sorted together into one big list. Which is a consequence of the way the flags work. With no flags, an array expands to its values. The *k *flag says "get the keys instead". The *v* fl= ag says "include the values, too". The resulting list alternates between keys and values, but it is still a flat, one-dimensional array; it has no internal structure keeping the pairs together. The sort triggered by the ordering flags has no way to know that it's a list of pairs. You could make the case that it should know that based on the flags; the flag triplets *kvo* and *kvO *could order just the keys while maintaining the pairwise association with their values, as a special case. Though that privileges the keys over the values; might one not also conceivably want to sort by value while maintaining the associated keys? In fact, as far as I can tell, there's currently no good way to get from a value to its associated key at all. If you want the key/value pairs in order with current zsh, there is a ready solution: simply iterate through the sorted keys returned by *ko* and use them to get the associated value: for key in "${(@ko)array}"; do ... something with "$key" and "${array[$key]}" here ... done But if you instead iterate through the values (with or without *o*), there's no analogous way to get back to the corresponding key. Maybe that's the missing functionality we should look into instead: inverting an associative array. Of course duplicate values are troublesome in this regard. --=20 Mark J. Reed --00000000000010766e060f4e65de Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable

On Fri, Jan 19, 2024 at 9:58=E2=80=AFAM Ray Andre= ws <rayandrews@eastlink.ca= > wrote:
<= /u>
So it seems that zsh al= ready does intend the ability to output the array in a declared way as Step= hane showed (hash tables notwithstanding).=C2=A0 Thus it's simply a mat= ter of making that work as it proposes to do.=C2=A0 Couldn't ask for mo= re.

Well, let's be clear about what's happeni= ng.

As a general rule, associative arrays, as implementa= tions of the abstract data type known as Map or Table, are fundamentally un= ordered, regardless of the implementation details. It's true that some = implementations naturally keep the keys in a recognizable order (e.g. binar= y trees in lexical order by key, association lists in insertion order), whi= le others (such as hash tables) do not, but such details don't necessar= ily dictate the features of any given implementation.

Most systems w= ith associative arrays don't provide a mechanism to retrieve the elemen= ts in a specified order. Some do =E2=80=93 Ksh93+ was brought up, and I men= tioned JavaScript, PHP, Python, and Ruby.=C2=A0 Sometimes this is an actual= feature and other times an accidental detail; in Clojure, maps that are sm= all enough (less than about eight pairs) are stored using a data structure = that keeps the keys in lexical order, so you might be lulled into thinking = that's true generally, but larger maps use a hash table and revert to a= seemingly unordered state.

Zsh has expansion flags that let you get= =C2=A0either=C2=A0the keys ( k=C2=A0) or the values in lexica= l order, ascending ( o ) or descending ( O=C2=A0).=C2=A0

Unfortunately it does not have a way to get the keys a= nd values simultaneously in any sort of meaningful order while=C2=A0maintai= ning the pairwise association. If you use both flags k and v= =C2=A0together with either o or O,=C2=A0you will get an undis= tinguished muddle of keys and values all=C2=A0sorted together into one big = list.

Which is a consequence of the way the flags = work. With no flags, an array expands to its values. The k flag says= "get the keys instead". The v=C2=A0flag says "includ= e the values, too". The=C2=A0resulting list alternates between keys an= d values, but it is still a flat, one-dimensional array; it has no internal= structure keeping the pairs together. The sort triggered by the ordering f= lags has no way to know that it's a list of pairs.

=
You could make the case that it should know that based on the flags; t= he flag triplets=C2=A0kvo=C2=A0and kvO=C2=A0could order just = the keys while maintaining the pairwise association with their values, as a= special case. Though that privileges the keys over the values; might one n= ot also conceivably want to sort by value while maintaining the associated = keys?

In fact, as far as I can tell, there's currently no good = way to get from a value to its associated key at all. If you want the key/v= alue pairs in order with=C2=A0current zsh, there is a ready solution: simpl= y iterate through the sorted keys returned by ko=C2=A0and use them t= o=C2=A0get the associated value:

=C2=A0 =C2=A0 for key in "${(@ko)array}"; do
=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ... something wit= h "$key" and "${array[$key]}" here ...
=C2=A0 =C2=A0 done

But if you instead iterate through the values (with or without=C2=A0o<= /b>), there's no analogous way to get back to the corresponding key.=C2= =A0Maybe that's the missing functionality we should look into instead: = inverting an associative array. Of course duplicate values are troublesome = in this regard.

--
Mark J. Reed= <markjreed@gma= il.com>
--00000000000010766e060f4e65de--