Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:117582 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 31123 invoked from network); 23 Apr 2022 21:07:46 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 23 Apr 2022 21:07:46 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 3C01A180380 for ; Sat, 23 Apr 2022 15:42:21 -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=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE 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-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) (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 ; Sat, 23 Apr 2022 15:42:20 -0700 (PDT) Received: by mail-ej1-f45.google.com with SMTP id g13so22863107ejb.4 for ; Sat, 23 Apr 2022 15:42:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=JVBsi5gfzDpompv9JDCE5Dq8CTeP/2y4Ra1qN+xVEFw=; b=j6/6E9kKHmiuEhqV5XOLvq9ixoxGblSrU1rWgy6Vmz1KwQJfqqyDhsGoeQs/rOADGZ HofCF4XY8GRJo9uE2oLK5okNkO83cJkWGZ+S71rNXM43Ypf9UUkL+8tRb/cCtRYe9MfX 3qB1/fFpy5Pt1b7QyeN2o8cHxFcWIzSn+Cx85He85PlLJchgZSV7xD52i52715HHYgEO +nPjGsb6kRdQr/LuU2zLPbz3HMhcheCjfUARVh6tVgqKjJlNZ8CwFzsfGbSTr/tRH3BY CX88kTstKQNKQJ00jK+0FOyEaBBrI+pE3lLGWV7/FEmMItj2NJl9auNct48KRdaDC5jZ jlXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=JVBsi5gfzDpompv9JDCE5Dq8CTeP/2y4Ra1qN+xVEFw=; b=2oAGFU9ZpoNQUtDbtXgS9e0fiyOy4H7i3o/ESUVw9Cm/smcXYoEbynr1NV8r9zVGMY YhYyomm754UBxQ7NrVk16eHAGR5Cp236lCPgaUBBgTz2qpOfnRq/jupUBWtrQqQQ596Z 2sZAq5TRjkzDaXyy6z2XzIoFbZz7hLNvA3pTLDU6MGq+yYdDg5PlQnpJqAQFqPeLZ3bq VfDkSdaDXki3N7i2fTZMbi0zlJ1eu7vo11vLWWLhrDJc4l5pmO6P8Xa8dHaCWrGznpDC Db2K3iuic45WGCd4RbFWJ9/e3aGX7f3PXO62qBqHak+5FLEVg2CeV4TkuouThuLI9O64 bZKA== X-Gm-Message-State: AOAM531B49VUDLs75XS+i6iD2DW2CB8b0MamOH9yJW4m1rmo4PWnPcYS 2oLPDkklMI3l5BepXRMTmBqq/XXlNQjSu1hOEoDd4VRi X-Google-Smtp-Source: ABdhPJyeVnCaaxYKJzFu5REVE0qARsWgSfybk1ok/ZgDyqw9U3fw8HTjlwvfVe5IA4teID5oK4HMxV5o4pX4ODjxt04= X-Received: by 2002:a17:906:3adb:b0:6b7:876c:d11b with SMTP id z27-20020a1709063adb00b006b7876cd11bmr9786950ejd.250.1650753738800; Sat, 23 Apr 2022 15:42:18 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a50:6ccc:0:0:0:0:0 with HTTP; Sat, 23 Apr 2022 15:42:18 -0700 (PDT) In-Reply-To: References: Date: Sun, 24 Apr 2022 08:42:18 +1000 Message-ID: To: internals@lists.php.net Content-Type: text/plain; charset="UTF-8" Subject: Discussion before submission of array_transpose() RFC From: mickmackusa@gmail.com (mickmackusa) I am seeking constructive feedback/advice that will give me the best chance of a successful RFC when I eventually submit it. Introduction: PHP developers have had an appetite for transposing data for many years; this is indicated by the nearly 100 Stack Overflow pages on this narrow topic. There are many non-native techniques being used to transpose multidimensional data sets, but each of them are some combination of verbose, convoluted, restrictive, and/or even flawed. Transposing comes in handy when re-orientating data for server-side storage or graphical/tabular display. Ideally, PHP should have a native transposing function to put developers out of their misery -- much like array_key_last() did. Proposal: Let's create an intuitive transposing function for data sets with a minimum depth of 2 levels. The function should also return the input parameter without complaint when the input parameter is an empty array/object. The previous two points are purposely stated so that this function can accommodate fetch-all result sets from database queries (e.g. array_transpose($stmt->fetchAll(PDO::FETCH_ASSOC));). As a matter of flexibility, there should be no requirement that the lone parameter be a matrix or dense data structure. It should also preserve keys to give it a clear advantage over pre-existing functional techniques. The function must never receive or return a non-empty one-dimensional array. A potential consideration is to preserve data types while transposing -- see implementation #2 and its demo link with test data. Background: Here are some of the popular techniques that this new function would replace: array_unshift($array, null); return call_user_func_array('array_map', $array); // outdated, unintuitive, unreliable, requires non-numeric first-level keys, destroys associative keys // [['single' => 'row']] becomes ['single' => 'row'] but should be ['single' => ['row']] return array_map(null, ...$array); // unintuitive, unreliable, requires non-numeric first-level keys, destroys associative keys // [['single' => 'row']] becomes ['single' => 'row'] but should be ['single' => ['row']] $out = []; foreach ($arr as $key => $subarr) { foreach ($subarr as $subkey => $subvalue) { $out[$subkey][$key] = $subvalue; } } return $out; // reliable, but verbose and not functional-style $keys = array_keys($array); return array_map(function($array) use ($keys) { return array_combine($keys, $array); }, array_map(null, ...array_values($array))); // convoluted, unintuitive, requires input to be a matrix // [['single' => 'row']] generates Warning: array_combine() expects parameter 2 to be array, string given" Considerations: Should the function unconditionally return an array of arrays? Should it preserve the initial data types of the first and second level? Should data type preservation be excluded to increase the chances of its implementation? Rough implementations of behavior: 1. Unconditionally cast output as array of arrays. function array_transpose(array|object $object_or_array): array|object { $levelOneType = gettype($object_or_array); if (!in_array($levelOneType, ['array', 'object'])) { throw new Exception("Error: array_transpose() expects parameter 1 to be an array or object, $levelOneType given"); } $result = []; foreach ($object_or_array as $rowKey => $row) { $levelTwoType = gettype($row); if (!in_array($levelTwoType, ['array', 'object'])) { throw new Exception("Error: array_transpose() expects parameter 1 to contain rows of arrays or objects, $levelTwoType given"); } foreach ($row as $columnKey => $value) { $result[$columnKey][$rowKey] = $value; } } return $result; } 2. Preserve original data types of level one and level two. https://3v4l.org/RRKlr (If input is two dimensional, then the first occurring data type in the second level will dictate the result's first level data type.) function array_transpose(array|object $object_or_array): array|object { $levelOneType = gettype($object_or_array); if (!in_array($levelOneType, ['array', 'object'])) { throw new Exception("Fatal error: Uncaught TypeError: array_transpose(): Argument #1 ($object_or_array) must be of type object|array, $levelOneType given"); } foreach ($object_or_array as $rowKey => $row) { $levelTwoType = gettype($row); if (!in_array($levelTwoType, ['array', 'object'])) { throw new Exception("Fatal error: Uncaught TypeError: array_transpose(): Argument #1 ($object_or_array) must contain rows of type object|array, $levelTwoType given"); } $result ??= ($levelTwoType === 'array' ? [] : (object)[]); foreach ($row as $columnKey => $value) { if ($levelTwoType === 'array') { if ($levelOneType === 'array') { $result[$columnKey][$rowKey] = $value; } else { $result[$columnKey]->$rowKey = $value; } } else { if (!property_exists($result, $columnKey)) { $result->$columnKey = ($levelOneType === 'array' ? [] : (object)[]); } if ($levelOneType === 'array') { $result->{$columnKey}[$rowKey] = $value; } else { $result->{$columnKey}->$rowKey = $value; } } } } return $result ?? ($levelOneType === 'array' ? [] : (object)[]); } RFC Impact: I can't see any backward incompatible concerns, but it is possible that this new native function may impact codes where the function name is already in use. (e.g. https://github.com/josefernandotrindade/array_transpose/blob/master/transpose.php) Pre-existing projects may have different rules relating to the specific handling of data types and data structures. No new constants. No php.ini defaults. Future Scope: If only initially implemented to return an array of arrays, then expanding the result data types in the future may be of interest. List of Stack Overflow pages which seek to implement transposition (approaching 100K page views in the aggregate): link list @ https://meta.stackoverflow.com/q/417663/2943403 2009 Transposing multidimensional arrays in PHP -- 50K views 2009 Joining Arrays in PHP -- 150 views 2010 Is there better way to transpose a PHP 2D array? -- 5K views 2010 Combine 3 or more arrays (php) -- 4K views 2010 Can I convert individual fields of a 'mysql_query' to arrays? -- 500 views 2011 Combine arrays in PHP 300 views 2011 PHP: Take several arrays, and make new ones based on shared indexes? -- 100 views 2011 Insert Multiple rows using implode -- 3K views 2011 how convert the element structure of an array in php -- 100 views 2011 php reassign array contents -- 150 views 2012 PHP Grouping Array by Index -- 1K views 2012 displaying a mysql table vertically - for comparison or for print out purposes -- 4K views 2012 Elegant way to convert associative array into an indexed one -- 3K views 2012 PHP Grouping Array by Index -- 1K views 2012 Order in loops foreach -- 350 views 2012 PHP Array, Move Elements -- 100 views 2013 Refactor (transpose) array to unique keys -- 200 views 2013 How to merge 3 arrays into one big array (same keys) -- 200 views 2013 Smarty/PHP - How to match up keys between 3 different arrays? -- 750 views 2013 PHP rotate matrix counter-clockwise -- 3K views 2013 loop to populate html table vertically -- 9K views 2013 How to merge 3 arrays into one big array (same keys) -- 200 views 2014 PHP looping array to get combined rows of items -- 50 views 2014 MYSQL / Query Builder / Eloquent - Transpose rows to columns -- 1k views 2014 Change several ARRAY into new ARRAYS -- 50 views 2014 array merge issue in php -- 50 views 2014 How to combine associative array by indexes -- 450 views 2014 PHP: Grouping array values by keys -- 150 views 2014 How to transpose two arrays to form an indexed array of associative arrays? -- 100 views 2014 PHP - multidimensional array from arrays -- 100 views 2014 Display transposed data as html table -- 100 views 2015 I have 5 arrays each array contains 10 values, I want to invert these arrays into 10 arrays and each array contains 5 values using php? -- 6K views 2015 create transpose matrix using php -- 6K views 2015 Why does array_map() with null as callback create an "array of arrays"? -- 2K views 2015 Chunk and transpose a flat array into rows with a specific number of columns -- 50 views 2015 Merge 2 arrays into 1 multidimensional array by index -- 800 views 2015 Merging two simple arrays into a multidimensional array -- 50 views 2015 Populating HTML table with multidimensional array vertically -- 1K views 2015 Merge multidimensional array preserving keys -- 100 views 2015 Transpose csv file data -- 300 views 2016 Multi dimensional loops from 4 existing arrays -- 50 views 2016 How to use an array of arrays with array_map(...) in PHP? -- 2K views 2016 How can I combine arrays in one multidimensional array in php? -- 50 views 2016 PHP array, move keys and values to new array, but mix it up -- 50 views 2016 How to transpose array elements? -- 900 views 2016 Hierarchical Array Conversion to Flat Array -- 300 views 2016 merge and reorder 3 arrays -- 50 views 2016 Insert database rows from columns of data from associative array of indexed arrays -- 50 views 2017 Transpose rows and columns in a 2D array -- 5K views 2017 php reformat array representation from html form array -- 50 views 2017 How to insert arrays into a main array in PHP to make it 2d array? -- 50 views 2017 How can I combine array's items? -- 250 views 2017 Restructure multidimensional array of column data into multidimensional array of row data -- 1K views 2017 Transpose associative array of associative arrays to create associative array of indexed arrays -- 4K views 2017 Merging PHP array to multidimensional array from another array -- 50 views 2018 Combine items of two array and create new array using php -- 50 views 2018 How to collect 3 arrays in 1 array using PHP? -- 50 views 2018 How do I use array_map recursively in PHP? -- 1K views 2018 Laravel loop through set of input arrays -- 150 views 2018 Foreach to combine to array -- 50 views 2019 php extract associate arrays -- 50 views 2019 How to combine and transpose 2 PHP arrays -- 50 views 2019 How to merge two arrays into one without iteration -- 100 views 2019 How to create an associative array from two arrays? -- 3K views 2019 how to get each column of values as array directly, and without using pluck laravel? -- 650 views 2019 Combine (merge) 2 arrays by keys and change keys name in the result array -- 800 views 2019 Array_map and array_combine for more than two arrays -- 500 views 2019 Merge values from different arrays to one with the same key -- 100 views 2019 Native PHP function that pairs elements from arbitrary number of input arrays -- 50 views 2019 Transpose multidimensional array and join values with commas -- 50 views 2019 How to create 3 arrays from 1 multidimensional array with 2 arrays inside -- 50 views 2019 How to store 3 key by index per row PHP -- 50 views 2019 How to change associative array value in php -- 400 views 2019 How to put array inside array in PHP? -- 50 views 2019 How to Loop through multi dimensional array of $_FILES array -- 200 views 2019 How to change associative array value in php -- 400 views 2019 PHP multi-dimensional array, merge duplicate keys into new arrays -- 50 views 2020 Transpose of column to row in php -- 50 views 2020 combine and merge array in laravel -- 100 views 2021 how to import a transposed excel in Laravel using laravel-excel -- 450 views 2021 Transpose imported Excel with Matrix table to Laravel -- 50 views 2021 Group multi array by key and value PHP -- 50 views 2021 Create a multidimensional array based on number of values -- 50 views 2022 Rotate a Collection in laravel -- 50 views 2022 Zip multiple arrays in PHP based on their identical keys and not their indices or their positions in array -- 50 views 2022 Convert nested associative array to single array in php -- 50 views Stack Overflow transposition pages not in PHP: What is the fastest way to transpose a matrix in C++? Transpose/Unzip Function (inverse of zip)? Transposing a 2D-array in JavaScript An efficient way to transpose a file in Bash Java: Multi-dimensional array transposing mickmackusa p.s. I've been told that I'll need a sprinkling of karma if I am going to submit an RFC, so please shout me some of that.