# Proposal: array_flatten function

- Thread: https://externals.io/message/42376
- Original archive: https://news-web.php.net/php.internals/42376
- Started by Mike Panchenko on 2008-12-26T09:06:10+00:00
- Messages: 12
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #42376 — Mike Panchenko — 2008-12-26T09:06:10+00:00

URL: https://externals.io/message/42376#42376

Hey everybody, I'm new both to the list and to hacking the internals, so
I'll try to keep it short and humble.

I've written an array_flatten function which just takes all elements from a
nested array and pushes them into a single indexed array.

Couple of questions:

1. Most importantly, is this patch-worthy to everybody? I was a bit
surprised that it didn't already exist (it wasn't difficult to write, even
for me :) ), and a search turns up quite a few posts both on the PHP doc
comments and elsewhere detailing how to do the same in usersland PHP. There
are some pretty clear usecases for this, such as doing statistics on a
grouped dataset, as well as grabbing all values from a single-column SQL
query. It's a very simple, unobtrusive patch.

2. One of the PHP implementations "preserved keys." This seems
counterintuitive to me, as there's a high probability of overwriting, and I
can't think of a usecase where one would want to flatten out an array, but
keep the keys. Nonetheless, it was implemented by one of the snippets I saw.
Should the function offer this option with a $preserveKeys = false optional
param? If so, how should I handle duplicate keys? Failure? Warning? IMO,
it's not worthwhile, but I wanted to get opinions.

3. (this is where the noob comes in) What is the protocol on creating
patches? Should I just run the CVS patch command against a major revision? I
haven't used that before, but it seems straight forward enough. If someone
can point me to a writeup of the exact "correct" way to generate a patch,
I'd appreciate it.

Ooops, not that short I guess... Cheers.

Mike.

---

## #42377 — Alexey Zakhlestin — 2008-12-26T09:23:51+00:00

URL: https://externals.io/message/42376#42377 · In reply to: #42376

> Hey everybody, I'm new both to the list and to hacking the internals, so
> I'll try to keep it short and humble.
>
> I've written an array_flatten function which just takes all elements from a
> nested array and pushes them into a single indexed array.
>
> Couple of questions:
>
> 1. Most importantly, is this patch-worthy to everybody? I was a bit
> surprised that it didn't already exist (it wasn't difficult to write, even
> for me :) ), and a search turns up quite a few posts both on the PHP doc
> comments and elsewhere detailing how to do the same in usersland PHP. There
> are some pretty clear usecases for this, such as doing statistics on a
> grouped dataset, as well as grabbing all values from a single-column SQL
> query. It's a very simple, unobtrusive patch.

regarding SQL: PDO has nice $stmt->fetchAll(PDO::FETCH_COLUMN) mode
which does exactly this :)

> 2. One of the PHP implementations "preserved keys." This seems
> counterintuitive to me, as there's a high probability of overwriting, and I
> can't think of a usecase where one would want to flatten out an array, but
> keep the keys. Nonetheless, it was implemented by one of the snippets I saw.
> Should the function offer this option with a $preserveKeys = false optional
> param? If so, how should I handle duplicate keys? Failure? Warning? IMO,
> it's not worthwhile, but I wanted to get opinions.
>
> 3. (this is where the noob comes in) What is the protocol on creating
> patches? Should I just run the CVS patch command against a major revision? I
> haven't used that before, but it seems straight forward enough. If someone
> can point me to a writeup of the exact "correct" way to generate a patch,
> I'd appreciate it.

"cvs diff -u" against 5.3 branch shoould be ok for the start.
after positive review, "cvs diff -u" against HEAD would be needed to


-- 
Alexey Zakhlestin
http://www.milkfarmsoft.com/

---

## #42378 — David Coallier — 2008-12-26T10:43:21+00:00

URL: https://externals.io/message/42376#42378 · In reply to: #42377

>
> "cvs diff -u" against 5.3 branch shoould be ok for the start.
> after positive review, "cvs diff -u" against HEAD would be needed to
>

I really have to say it, you should make your changes to HEAD
__first__ then to 5.3. Not the other way around :)

-- 
Slan,
David

---

## #42379 — Alexey Zakhlestin — 2008-12-26T10:55:54+00:00

URL: https://externals.io/message/42376#42379 · In reply to: #42378

> > […]
>
> I really have to say it, you should make your changes to HEAD
> __first__ then to 5.3. Not the other way around :)

David, it's not about changes. It's about review.
Raw fact is, that reviewing on 5.3 is much easier than on HEAD for many people.

At the moment of commit both patches are needed, for sure :)

-- 
Alexey Zakhlestin
http://www.milkfarmsoft.com/

---

## #42380 — Mike Panchenko — 2008-12-26T11:27:42+00:00

URL: https://externals.io/message/42376#42380 · In reply to: #42379

Well, I've made a patch against 5.3 for now, let me know if there are issues
with it (I'm sure there are) and if you want the HEAD patch. Cheers.

Mike.

On Fri, Dec 26, 2008 at 2:55 AM, Alexey Zakhlestin <indeyets@gmail.com>wrote:

> 
> > […]
>
> David, it's not about changes. It's about review.
> Raw fact is, that reviewing on 5.3 is much easier than on HEAD for many
> people.
>
> At the moment of commit both patches are needed, for sure :)
>
> --
> Alexey Zakhlestin
> http://www.milkfarmsoft.com/

---

## #42381 — Kevin Waterson — 2008-12-26T13:55:23+00:00

URL: https://externals.io/message/42376#42381 · In reply to: #42376

This one time, at band camp, "Mike Panchenko" <m@mihasya.com> wrote:

> Hey everybody, I'm new both to the list and to hacking the internals, so
> I'll try to keep it short and humble.
> 
> I've written an array_flatten function which just takes all elements from a
> nested array and pushes them into a single indexed array.

function flattenArray(array $array){
   $ret_array = array();
   foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array)) as $value)
   {
     $ret_array[] = $value;
   }
   return $ret_array;
  }

Kevin

---

## #42382 — Lukas Kahwe Smith — 2008-12-26T15:56:16+00:00

URL: https://externals.io/message/42376#42382 · In reply to: #42376

> Hey everybody, I'm new both to the list and to hacking the  
> internals, so
> I'll try to keep it short and humble.
>
> I've written an array_flatten function which just takes all elements  
> from a
> nested array and pushes them into a single indexed array.
>
> Couple of questions:
>
> 1. Most importantly, is this patch-worthy to everybody? I was a bit
> surprised that it didn't already exist (it wasn't difficult to  
> write, even
> for me :) ), and a search turns up quite a few posts both on the PHP  
> doc
> comments and elsewhere detailing how to do the same in usersland  
> PHP. There
> are some pretty clear usecases for this, such as doing statistics on a
> grouped dataset, as well as grabbing all values from a single-column  
> SQL
> query. It's a very simple, unobtrusive patch.
>
> 2. One of the PHP implementations "preserved keys." This seems
> counterintuitive to me, as there's a high probability of  
> overwriting, and I
> can't think of a usecase where one would want to flatten out an  
> array, but
> keep the keys. Nonetheless, it was implemented by one of the  
> snippets I saw.
> Should the function offer this option with a $preserveKeys = false  
> optional
> param? If so, how should I handle duplicate keys? Failure? Warning?  
> IMO,
> it's not worthwhile, but I wanted to get opinions.
>
> 3. (this is where the noob comes in) What is the protocol on creating
> patches? Should I just run the CVS patch command against a major  
> revision? I
> haven't used that before, but it seems straight forward enough. If  
> someone
> can point me to a writeup of the exact "correct" way to generate a  
> patch,
> I'd appreciate it.

In one of my recent projects I had the need for something like this. I  
essentially had a recursive data structure of organizations and  
frequently I had to get a list of all organization ID's that were  
above or underneath a given organization. So I had to write a deeply  
self join which would produce lets say around 3-4 columns that either  
contained an ID or were NULL.

I ended up with an implementation like the following. Actually looking  
at it now it seems way too complex but it works, so it goes:
     function flattenArray($array) {
         if (empty($array)) {
             return array();
         }
         $first = reset($array);
         if (empty($first)) {
             return array();
         }
         $keys = array_keys($first);
         $result = array();
         foreach ($array as $row) {
             foreach ($keys as $key) {
                 if (!empty($row[$key])) {
                     $result[] = $row[$key];
                 }
             }
         }
         $result = array_unique($result);
         return $result;
     }

So I guess what I am asking for is a flag to ignore NULL's. Kind of  
reminds me of that patch Igor proposed the other day. Then again, we  
have sooooo many array functions its not even funny. So maybe we  
really should look more towards Iterators to help us consolidate  
things. Not sure.

regards,
Lukas

---

## #42383 — Mike Panchenko — 2008-12-26T18:04:23+00:00

URL: https://externals.io/message/42376#42383 · In reply to: #42381

Why not just link straight to the tutorial on your site? ;) Not sure what
your point is, other than "there's a way to do this in userland," which I
cover in my email. Maybe some sentences to accompany it would make it easier
to understand.

Thanks for reading. Cheers.

Mike.



> This one time, at band camp, "Mike Panchenko" <m@mihasya.com> wrote:
>
> > […]
> a
> > […]
>
> function flattenArray(array $array){
>   $ret_array = array();
>   foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array))
> as $value)
>   {
>     $ret_array[] = $value;
>   }
>   return $ret_array;
>  }
>
> Kevin

---

## #42384 — Mike Panchenko — 2008-12-26T18:28:28+00:00

URL: https://externals.io/message/42376#42384 · In reply to: #42382

Lukas,

Hmmm I'm just trying to solve the basic problem (hence my skepticism towards
preserving keys - it seems an edge case). I think once you get to more
specific requirements, iterators are probably the way to go, since all the
standard functions you could use to shorten this would re-iterate over the
array internally anyway.

Cheers.

Mike.

On Fri, Dec 26, 2008 at 7:56 AM, Lukas Kahwe Smith <mls@pooteeweet.org>wrote:

> In one of my recent projects I had the need for something like this. I
> essentially had a recursive data structure of organizations and frequently I
> had to get a list of all organization ID's that were above or underneath a
> given organization. So I had to write a deeply self join which would produce
> lets say around 3-4 columns that either contained an ID or were NULL.
>
> I ended up with an implementation like the following. Actually looking at
> it now it seems way too complex but it works, so it goes:
>    function flattenArray($array) {
>        if (empty($array)) {
>            return array();
>        }
>        $first = reset($array);
>        if (empty($first)) {
>            return array();
>        }
>        $keys = array_keys($first);
>        $result = array();
>        foreach ($array as $row) {
>            foreach ($keys as $key) {
>                if (!empty($row[$key])) {
>                    $result[] = $row[$key];
>                }
>            }
>        }
>        $result = array_unique($result);
>        return $result;
>    }
>
> So I guess what I am asking for is a flag to ignore NULL's. Kind of reminds
> me of that patch Igor proposed the other day. Then again, we have sooooo
> many array functions its not even funny. So maybe we really should look more
> towards Iterators to help us consolidate things. Not sure.
>
> regards,
> Lukas

---

## #42385 — Kevin Waterson — 2008-12-27T08:10:15+00:00

URL: https://externals.io/message/42376#42385 · In reply to: #42383

This one time, at band camp, "Mike Panchenko" <m@mihasya.com> wrote:

> Why not just link straight to the tutorial on your site? ;) Not sure what
> your point is, other than "there's a way to do this in userland," which I
> cover in my email. Maybe some sentences to accompany it would make it easier
> to understand.

The last thing that is needed, is more array functions..

Kevin

---

## #42387 — Brian Moon — 2008-12-27T15:11:33+00:00

URL: https://externals.io/message/42376#42387 · In reply to: #42385

> The last thing that is needed, is more array functions..

I would agree except that doing lots of work on arrays in user space 
consumes a lot of memory because of the number of opcodes used when 
working on removing/adding things to the array.

We created an extension for Phorum to do our array tree sorting for 
those users that had large threads of messages (1000+).  We found that 
PHP would quickly consume a memory limit of 128MB and use tons of CPU 
when working in user space to simply reorder an array.

So, in that case, doing the work in a good C function will beat out user 
space work on arrays.

-- 

Brian Moon
Senior Web Engineer
------------------------------
When you care enough to spend the very least.
http://dealnews.com/

---

## #42388 — Kevin Waterson — 2008-12-28T00:08:08+00:00

URL: https://externals.io/message/42376#42388 · In reply to: #42387

This one time, at band camp, Brian Moon <brianm@dealnews.com> wrote:

> I would agree except that doing lots of work on arrays in user space 
> consumes a lot of memory because of the number of opcodes used when 
> working on removing/adding things to the array.

This is exactly the scenario for which SPL Iterators were created

> We created an extension for Phorum to do our array tree sorting for 
> those users that had large threads of messages (1000+).  We found that 
> PHP would quickly consume a memory limit of 128MB and use tons of CPU 
> when working in user space to simply reorder an array.
Were you using SPL Iterators?

Kevin
