Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clobbering lacks support for merging non-associative array values #31

Closed
colinodell opened this issue Oct 3, 2020 · 0 comments · Fixed by #32
Closed

Clobbering lacks support for merging non-associative array values #31

colinodell opened this issue Oct 3, 2020 · 0 comments · Fixed by #32

Comments

@colinodell
Copy link
Contributor

colinodell commented Oct 3, 2020

Data::import(), Data::importData(), and Util::mergeAssocArray() support this notion of "clobbering" when trying to merge in two arrays. In a nutshell:

$clobber Value Behavior
false Values from the original array are preserved
true Values from the second array overwrite the first

For example:

$a = ['x' => 'a', 'foo' => ['foo'], 'a' => true];
$b = ['x' => 'b', 'foo' => ['bar'], 'b' => true];

Util::mergeAssocArray($a, $b, false);
// ['x' => 'a', 'foo' => ['foo'], 'a' => true, 'b' => true]

Util::mergeAssocArray($a, $b, true);
// ['x' => 'b', 'foo' => ['bar'], 'a' => true, 'b' => true]

However, there's no ability to merge non-associative array values. In the example above, it's impossible for me to have the foo key contain ['foo', 'bar').

To give a more realistic example, I might have Data elements representing HTML tag attributes:

$attributes = [
    'id' => 'logo',
    'class' => ['img-responsive'],
    'alt' => 'My logo',
];

And I want to merge in some additional attributes:

$more = [
    'class' => ['box-shadow'],
    'alt' => 'Our Awesome Logo',
];

In order to get this output:

[
    'id' => 'logo',
    'class' => ['img-responsive', 'box-shadow'],
    'alt' => 'Our Awesome Logo',
];

Unfortunately neither $clobber mode allows this.

Proposal

Add a third mode which acts more like PHP's array_merge() function - it will clobber things with string keys but append things with numeric keys.

To do this, we'll create three constants, one for each mode:

public const PRESERVE = 0; // equivalent to `false` in 1.x
public const REPLACE = 1; // equivalent to `true` in 1.x; default value
public const MERGE = 2; // the new approach I'm proposing

We'd also rename $clobber to $mode since it's no longer all-or-nothing.

This approach provides some level of backward-compatibility for anyone not using strict types, as false gets coerced to 0 and true gets coerced to 1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant