neos / flow-development-collection

The unified repository containing the Flow core packages, used for Flow development.
https://flow.neos.io/
MIT License
138 stars 188 forks source link

Array.filter Eel helper converts flat array to associative array in some cases #1568

Open Sebobo opened 5 years ago

Sebobo commented 5 years ago

Description

When using the Eel helper Array.filter flat array without keys can turn into associative array which might break other code.

This is the example from the docs

Array.filter(['foo', 'bar', 'baz'], (x, index) => index < 2) // == ['foo', 'bar']

This changed example will return something else:

${Array.filter(['foo', 'bar', 'baz'], (x, index) => x == 'bar')} // == [1: 'bar']

Steps to Reproduce

Run the second example in Fusion.

Expected behavior

The filter operation still returns a flat array.

Actual behavior

The filter operation returns an associative array

Affected Versions

Neos: 3.3 Flow: 4.3

Sebobo commented 5 years ago

As this is correct PHP behavior, it's annoying in Fusion to handle.

Maybe the helper should check this do an array_values on the result if it was an indexed array.

albe commented 5 years ago

Ugh, yeah. PHP's behaviour with Arrays is weird, especially since there's no good means to differenciate between flat array and associative, other than manually checking the keys are numeric and increasing from 0.

function isFlat(array $array)
{
    if ($array=== [] || !isset($array[0])) return false;  // Empty array is considered associative
    return array_keys($array) !== range(0, count($array) - 1);
}

Would do the trick, but having to check that for every filter call might be prohibitive performance wise for the common case of passing a (non-small) flat array:

${Array.filter(['foo', 'bar', 'baz', ... a couple hundred other items], (x, index) => x == 'bar')}
Sebobo commented 5 years ago

I'm not 100% sure right now on how to solve this in the best way. Just think it's a mean trap right now.

One could provide a flag that forces the return of only the values or also add the values method as separate method for the ArrayHelper.

But in any case, the documentation should be extended to remind people that the result is not necessarily what they expect, when they are not PHP array experts.