Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:116010 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 27697 invoked from network); 8 Sep 2021 14:10:45 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 8 Sep 2021 14:10:45 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 6943B180504 for ; Wed, 8 Sep 2021 07:48:29 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 8 Sep 2021 07:48:29 -0700 (PDT) Received: by mail-pl1-f178.google.com with SMTP id j2so1480657pll.1 for ; Wed, 08 Sep 2021 07:48:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dqxtech-net.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=LU4PdDsDAVsBPRDxAGXz2SunevmwIotkua+9OwWsCTg=; b=YBxkmCTHpgfRGMCETNz+Uom6wVyRpPakPJBoVjUfYl5Xx4cnCf9R/xYDqMbn86epb8 A2mN3uLjo/rAL7qCAG32+vHslwsVXPkuRuOeiju02LcrJYsCsLf0QsY3ioPJ4452YF41 p71Sp/dPxZDLu9VzWVHGoryCfYFJdqKezrIivKOeN3YYlhke9cziqgdrxmicekqbbr2B r8uyFA65B8imZhuj94ln+5H5woAUp4M7OPh71jrIB0EAkm5glXSI0dpm0CHJtbNPEUf6 STu1Dntk9zPMchz0uoYzodr7vw6vsYhxgr+H2S+T76nRrwLffmGl+7JClcZS5eGfeL8a zIgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=LU4PdDsDAVsBPRDxAGXz2SunevmwIotkua+9OwWsCTg=; b=WIhcJGKb94PZQFKw7b/2XNqFapb6hwi7XyMcgnCgDd9HXwMVgFLHw0fn2o05M8bWn8 c2mU3OzMuZCNnOxIncYZxU9CGVcraikTJm4GlvxnB1/+kHSMQP5JwEa/DESLcnNG+DTz XHApW6UShGKIh9/4uV9NeKNUbw5i++fsXanDKvES13Ps/vMgz32Ou71OB2eLqh7yll3L upKrcvYh4eU9gUEsJ+G0+h9Cq20AFUETklC4O01jz2B9hkb9tWntm36YLSNY2S11Uye1 K3F0r8k6XxMJvHjOl4ZJTGqWi3qtwRUeh6lJyfRadmpKO6SGbWHCkmV6U3hiED6ARIkj ESGA== X-Gm-Message-State: AOAM530eDYiIpky4MooDESpCWjSYlFui5N/XGQpqsZOnr9KK9Xf/sf2P GalSXRNJ7VjlB+TGuYYqoNrjyylxAlwlUtxqVorJ3TXa487rHA== X-Google-Smtp-Source: ABdhPJxkDhwBIi7gi2DjVPQoHxx9C8Z+2JYifrZswKQFadfS5q4g+qZ3jyhX9ph4Glcbwt34aZm5xgbf2Lroh0Euu4M= X-Received: by 2002:a17:902:7ed0:b0:138:d64c:7c4 with SMTP id p16-20020a1709027ed000b00138d64c07c4mr3390524plb.1.1631112505300; Wed, 08 Sep 2021 07:48:25 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 8 Sep 2021 16:48:14 +0200 Message-ID: To: Marco Pivetta Cc: PHP internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Option for array_column() to preserve keys. From: andreas@dqxtech.net (Andreas Hennings) On Wed, 8 Sept 2021 at 16:10, Andreas Hennings wrote: > > Thanks for the feedback so far! > > On Wed, 8 Sept 2021 at 10:13, Marco Pivetta wrote: > > > > Heyo, > > > > On Wed, 8 Sep 2021, 02:19 Andreas Hennings, wrote= : > >> > >> Hello internals, > >> > >> The function array_column() would be much more useful if there was an > >> option to preserve the original array keys. > >> I can create an RFC, but I think it is better to first discuss the opt= ions. > > > > > > New function, please =F0=9F=99=8F > > I am not opposed. But I am also curious what others think. > What I don't like so much is how the situation with two different > functions will have a "historically grown wtf" smell about it. > But this is perhaps preferable to BC breaks or overly "magic" > parameters or overly crowded signatures. > > If we go for a new function: > A name could be array_column_assoc(). > > array_column_assoc(array $array, string $value_key) > > This would behave the same as array_column($array, $value_key), but > preserve original keys. > Items which are not arrays or which lack the key will be omitted. > A $value_key =3D=3D=3D NULL would be useless, because this would simply > return the original array. > > The question is, should it do anything beyond the most obvious? > Or should we leave it minimal for now, with the potential for > additional parameters in the future? > > Limitations: > If some items are omitted, it will be awkward to restore the missing > items while preserving the order of the array. > > Possible ideas for additional functionality: > - Replicate a lot of the behavior of array_column(), e.g. with an > optional $index_key parameter. This would be mostly redundant. > - Additional functionality for nested arrays? > - Fallback value for entries that don't have the key? Or perhaps even > a fallback callback like with array_map()? > - Option to capture missing entries e.g. in a by-reference variable? > > A benefit of keeping the limited functionality would be that > programming errors are revealed more easily due to the strict > signature. > > A question is how we would look at this long term: > Do we want both functions to co-exist long-term, or do we want to > deprecate one of them at some point? > If array_column() is going to stay, then array_column_assoc() only > needs to cover the few use cases that are missing. > > -- Andreas If we want to support nested array structures, it could work like this: NOTE: We actually don't need to squeeze this into array_column_assoc(). We could easily introduce a 3rd function instead, e.g. array_column_recursive(), if/when we want to have this in the future. I am only posting this so that we get an idea about the surrounding design space. $source['a']['b']['x']['c']['y'] =3D 5; $expected['a']['b']['c'] =3D 5; assert($expected =3D=3D=3D array_column_assoc($source, [null, null, 'x', nu= ll, 'y'])); Note the first NULL, which only exists to make the system feel more "comple= te". This could be useful if the array is coming from a function call. The following examples show this: unset($source, $expected); // (reset vars) $source['a']['x']['b'] =3D 5; $expected['a']['b'] =3D 5; assert($expected =3D=3D=3D array_column_assoc($source, [null, 'x'])); assert($expected =3D=3D=3D array_column_assoc($source, 'x')); unset($source, $expected); // (reset vars) $source['x']['a'] =3D 5; $expected['a'] =3D 5; assert($expected =3D=3D=3D array_column_assoc($source, ['x'])); assert($expected =3D=3D=3D $source['x'] ?? []); Trailing NULLs do almost nothing, except to ensure that non-arrays are removed from the tree. I would have to think more about the details, but I think it would work like this: unset($source, $expected); // (reset vars) $source['a0']['b'] =3D 5; $source['a1'] =3D 5; $expected =3D $actual; assert($expected =3D=3D=3D array_column_assoc($source, [])); assert($expected =3D=3D=3D array_column_assoc($source, [null])); unset($expected['a1']); assert($expected =3D=3D=3D array_column_assoc($source, [null, null])); unset($expected['a0']); assert($expected =3D=3D=3D array_column_assoc($source, [null, null])); Another idea could be to "collapse" array levels, using a magic value other than NULL, that does not work as an array key. unset($source, $expected); // (reset vars) $source['a0']['b0'] =3D 5; $source['a1']['b1'] =3D 5; $expected['b0'] =3D 5; $expected['b1'] =3D 5; assert($expected =3D=3D=3D array_column_assoc($source, [false])); unset($expected); $expected['a0'] =3D 5; $expected['a1'] =3D 5; assert($expected =3D=3D=3D array_column_assoc($source, [null, false])); -- Andreas