Giter Club home page Giter Club logo

arrays's Introduction

Yii

Yii Arrays


Latest Stable Version Total Downloads Build status Code Coverage Mutation testing badge static analysis type-coverage

The package provides:

  • ArrayHelper that has static methods to work with arrays;
  • ArraySorter that has static methods for sort arrays;
  • ArrayAccessTrait provides the implementation for \IteratorAggregate, \ArrayAccess and \Countable;
  • ArrayableInterface and ArrayableTrait for use in classes who want to support customizable representation of their instances.

Requirements

  • PHP 8.0 or higher.

Installation

composer require yiisoft/arrays

ArrayHelper usage

Array helper methods are static so usage is like the following:

$username = \Yiisoft\Arrays\ArrayHelper::getValue($_POST, 'username');

Overall the helper has the following method groups.

Getting data

  • getValue
  • getValueByPath
  • getColumn
  • getObjectVars

Setting data

  • addValue
  • addValueByPath
  • setValue
  • setValueByPath

Removing data

  • remove
  • removeByPath
  • removeValue

Detecting array types

  • isIndexed
  • isAssociative

HTML encoding and decoding values

  • htmlDecode
  • htmlEncode

Testing against arrays

  • isIn
  • isSubset

Transformation

  • index
  • group
  • filter
  • map
  • merge
  • parametrizedMerge
  • renameKey
  • toArray

Other

  • keyExists
  • pathExists

ArraySorter usage

Array sorter has one static method which usage is like the following:

\Yiisoft\Arrays\ArraySorter::multisort($data, ['age', 'name'], [SORT_ASC, SORT_DESC]);

ArrayAccessTrait usage

ArrayAccessTrait provides the implementation for \IteratorAggregate, \ArrayAccess and \Countable.

Note that ArrayAccessTrait requires the class using it contain a property named data which should be an array. The data will be exposed by ArrayAccessTrait to support accessing the class object like an array.

Example of use:

use \Yiisoft\Arrays\ArrayAccessTrait;

class OfficeClassification implements \IteratorAggregate, \ArrayAccess, \Countable
{
    use ArrayAccessTrait;

    public array $data = [
        'a' => 'Class A',
        'b' => 'Class B',
        'c' => 'Class C',
    ];
}

$classification = new OfficeClassification();

echo 'Count classes: ' . $classification->count() . "\n"; // 3

$iterator = $classification->getIterator();
while ($iterator->valid()) {
    echo $iterator->current() . "\n"; // Class A, Class B, Class C
    $iterator->next();
}

ArrayableInterface and ArrayableTrait usage

ArrayableInterface and its implementation ArrayableTrait intended for use in classes who want to support customizable representation of their instances.

Example of use:

use \Yiisoft\Arrays\ArrayableTrait;
use \Yiisoft\Arrays\ArrayableInterface;

class Car implements ArrayableInterface
{
    use ArrayableTrait;

    public string $type = 'Crossover';
    public string $color = 'Red';
    public int $torque = 472;
}

$car = new Car();

$data = $car->toArray(['type', 'color']); // ['type' => 'Crossover', 'color' => 'Red']

Documentation

If you need help or have a question, the Yii Forum is a good place for that. You may also check out other Yii Community Resources.

License

The Yii Arrays is free software. It is released under the terms of the BSD License. Please see LICENSE for more information.

Maintained by Yii Software.

Support the project

Open Collective

Follow updates

Official website Twitter Telegram Facebook Slack

arrays's People

Contributors

arhell avatar arogachev avatar dependabot-preview[bot] avatar dependabot[bot] avatar devanych avatar fantom409 avatar ganigeorgiev avatar germanow avatar hiqsol avatar kutuzovska avatar luizcmarin avatar machour avatar mapeveri avatar roxblnfk avatar rustamwin avatar sagittaracc avatar samdark avatar sankaest avatar silverfire avatar skugarev avatar spell6inder avatar strorch avatar stylecibot avatar terabytesoftw avatar tigrov avatar viktorprogger avatar vjik avatar xepozz avatar yiiliveext avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arrays's Issues

update src folder link

What steps will reproduce the problem?

What is the expected result?

What do you get instead?

Additional info

Q A
Version 1.0.?
PHP version
Operating system

call getter for property if getter exists.

What steps will reproduce the problem?

class Person {
    private $test = 'asefasef';
    
    public function getTest() 
    {
        return 123123;
    }
    
}
$testValue = \Yiisoft\Arrays\ArrayHelper::getValue($person, 'test');

What is the expected result?

use getter method, output:
123123

What do you get instead?

Fatal error: Uncaught Error: Cannot access private property Person::$test in /usr/src/myapp/vendor/yiisoft/arrays/src/ArrayHelper.php:250
Stack trace:

Additional info

If u use Symfony\Component\PropertyAccess\PropertyAccess you will get output:
123123

and maybe add some configuring options like in PropertyAccess:

$propertyAccessorBuilder->enableMagicCall(); // enables magic __call
$propertyAccessorBuilder->enableMagicGet(); // enables magic __get
$propertyAccessorBuilder->enableMagicSet(); // enables magic __set
$propertyAccessorBuilder->enableMagicMethods(); // enables magic __get, __set and __call

$propertyAccessorBuilder->disableMagicCall(); // disables magic __call
$propertyAccessorBuilder->disableMagicGet(); // disables magic __get
$propertyAccessorBuilder->disableMagicSet(); // disables magic __set
$propertyAccessorBuilder->disableMagicMethods(); // disables magic __get, __set and __call
Q A
Version 1.0.?
PHP version 7.4
Operating system

Requiring PHP 7.2

Why should this require PHP ^7.2 when Yii 3 requires ^7.1? If I have only php 7.1 available (as happens in the work environment) I can't use this lib with Yii 3.

I am aware this is a fw independent lib, but certainly it will be used primarily with Yii 3.

Get array value by matcher

What the problem?

arrays/src/ArrayHelper.php

Lines 210 to 212 in c3d14a3

if ($key instanceof Closure) {
return $key($array, $default);
}

Current implementation of getValue($array, $key) with $key as anonymous function is not match with the phrases Retrieves the value of an array element. basically it just like a value transformation, it can returns anything even value from outside array itself as of in example

arrays/src/ArrayHelper.php

Lines 184 to 188 in c3d14a3

* // Working with anonymous function:
* $fullName = \Yiisoft\Arrays\ArrayHelper::getValue($user, function ($user, $defaultValue) {
* return $user->firstName . ' ' . $user->lastName;
* });
*

What is the expected result?

the implementation should search value of an array by matcher function

    if ($key instanceof Closure) {
        foreach ($array as $key => $value) {
            if ($key($value, $key)) {
                return $value;
            }
        }

        return $default;
    }

and then, change the signature of matcher function to be function($value, $key): bool .

Additional info

Q A
Version 1.0.?
PHP version
Operating system

update irc link

What steps will reproduce the problem?

What is the expected result?

What do you get instead?

Additional info

Q A
Version 1.0.?
PHP version
Operating system

remove the unexpeced get/set effects

The suggestion for logic of getValue and setValue.

intro

there is some odd effect. let's see the example:

$value = ArrayHelper::getValue(
 ['a' => ['b' => ['c' => 'value']]],
'a.b.c'
);

 // $value === 'value'

$newArray = ['a' => ['b' => ['c' => 'old']]];

ArrayHelper::setValue($newArray, 'a.b.c', 'new');
// $newArray === ['a' => ['b' => ['c' => 'old']], 'a.b.c' => 'new'];

another variant of implementation:

$value = ArrayHelper::getValue(
 ['a.b.c' => value'],
'a.b.c'
);

 // $value === 'value'

$newArray = ['a.b.c' => 'old'];

ArrayHelper::setValue($newArray, 'a.b.c', 'new');
// $newArray === ['a.b.c' => 'old', 'a' => ['b' => ['c' => 'new']]];

as we can see - the fact result differs from expected. that's bad.

the suggestion

it would be good to drop the explode key by dots.
Instead of it, the composite key shoud be passed as array only:

$value = ArrayHelper::getValue(['a' => ['b' => ['c' => 'value']]], 'a.b.c' );
// $value === null;

$value = ArrayHelper::getValue(['a' => ['b' => ['c' => 'value']]], ['a', 'b', 'c'] );
// $value = 'value';

$value = ArrayHelper::getValue(['a' => ['b' => ['c' => 'value']]], explode('.', 'a.b.c'));
// $value = 'value';

$array = ['a' => ['b' => ['c' => 'value']]];
ArrayHelper::setValue($array, 'a.b.c', 'new' );
// $array ===  ['a' => ['b' => ['c' => 'value']], 'a.b.c' => 'new'];

$array = ['a' => ['b' => ['c' => 'value']]];
ArrayHelper::setValue($array, ['a', 'b', 'c'], 'new' );
// $array ===  ['a' => ['b' => ['c' => 'new']]];

$array = ['a' => ['b' => ['c' => 'value']]];
ArrayHelper::setValue($array, explode('.', 'a.b.c'), 'new');
// $array ===  ['a' => ['b' => ['c' => 'new']]];

so, the behavior is fixed and predictable, no strange effects.
in case of using objects, dots in keys are bad, but anyway, it's possible to use any keys such as '!s,o$m#e 1key',
and there is no big difference.

Q A
Version dev
PHP version any
Operating system any

Psalm 5.23.1

Psalm version Psalm 5.23.1

ArrayableTrait.php - no copability with psalm version 5.23.1 and errorLevel=1

ERROR: MixedAssignment - vendor/yiisoft/arrays/src/ArrayableTrait.php:132:70 - Unable to determine the type that $definition is being assigned to (see https://psalm.dev/032)
        foreach ($this->resolveFields($fields, $expand) as $field => $definition) {

  The type of $definition is sourced from here - vendor/yiisoft/arrays/src/ArrayableTrait.php:230:69
    protected function resolveFields(array $fields, array $expand): array



ERROR: MixedAssignment - vendor/yiisoft/arrays/src/ArrayableTrait.php:133:13 - Unable to determine the type that $attribute is being assigned to (see https://psalm.dev/032)
            $attribute = is_string($definition) ? $this->$definition : $definition($this, $field);


ERROR: MixedFunctionCall - vendor/yiisoft/arrays/src/ArrayableTrait.php:133:72 - Cannot call function on mixed (see https://psalm.dev/185)
            $attribute = is_string($definition) ? $this->$definition : $definition($this, $field);


ERROR: MixedArgumentTypeCoercion - vendor/yiisoft/arrays/src/ArrayableTrait.php:136:66 - Argument 2 of App\Dota\Match\Form\MatchDetailsLoadForm::extractFieldsFor expects string, but parent type array-key provided (see https://psalm.dev/194)
                $nestedFields = $this->extractFieldsFor($fields, $field);

  The type of $field is sourced from here - vendor/yiisoft/arrays/src/ArrayableTrait.php:230:69
    protected function resolveFields(array $fields, array $expand): array



ERROR: MixedArgumentTypeCoercion - vendor/yiisoft/arrays/src/ArrayableTrait.php:137:66 - Argument 2 of App\Dota\Match\Form\MatchDetailsLoadForm::extractFieldsFor expects string, but parent type array-key provided (see https://psalm.dev/194)
                $nestedExpand = $this->extractFieldsFor($expand, $field);

  The type of $field is sourced from here - vendor/yiisoft/arrays/src/ArrayableTrait.php:230:69
    protected function resolveFields(array $fields, array $expand): array



ERROR: MixedAssignment - vendor/yiisoft/arrays/src/ArrayableTrait.php:144:13 - Unable to determine the type of this assignment (see https://psalm.dev/032)
            $data[$field] = $attribute;


ERROR: MixedAssignment - vendor/yiisoft/arrays/src/ArrayableTrait.php:155:59 - Unable to determine the type that $field is being assigned to (see https://psalm.dev/032)
        foreach (array_merge($rootFields, $rootExpand) as $field) {

  The type of $field is sourced from here - vendor/vimeo/psalm/stubs/CoreGenericFunctions.phpstub:376:12
 * @return array<TKey, TValue>



ERROR: MixedArgument - vendor/yiisoft/arrays/src/ArrayableTrait.php:156:34 - Argument 1 of array_key_exists cannot be mixed, expecting array-key (see https://psalm.dev/030)
            if (array_key_exists($field, $array)) {

  The type of $field is sourced from here - vendor/vimeo/psalm/stubs/CoreGenericFunctions.phpstub:376:12
 * @return array<TKey, TValue>



ERROR: MixedAssignment - vendor/yiisoft/arrays/src/ArrayableTrait.php:157:17 - Unable to determine the type that $attribute is being assigned to (see https://psalm.dev/032)
                $attribute = $array[$field];

  The type of $attribute is sourced from here - vendor/yiisoft/arrays/src/ArrayableTrait.php:150:44
    private function filterAndExpand(array $array, array $fields = [], array $expand = []): array



ERROR: MixedArgument - vendor/yiisoft/arrays/src/ArrayableTrait.php:158:66 - Argument 2 of App\Dota\Match\Form\MatchDetailsLoadForm::extractFieldsFor cannot be mixed, expecting string (see https://psalm.dev/030)
                $nestedFields = $this->extractFieldsFor($fields, $field);

  The type of $field is sourced from here - vendor/vimeo/psalm/stubs/CoreGenericFunctions.phpstub:376:12
 * @return array<TKey, TValue>



ERROR: MixedAssignment - vendor/yiisoft/arrays/src/ArrayableTrait.php:165:17 - Unable to determine the type of this assignment (see https://psalm.dev/032)
                $data[$field] = $attribute;


ERROR: MixedAssignment - vendor/yiisoft/arrays/src/ArrayableTrait.php:184:29 - Unable to determine the type that $field is being assigned to (see https://psalm.dev/032)
        foreach ($fields as $field) {

  The type of $field is sourced from here - vendor/yiisoft/arrays/src/ArrayableTrait.php:180:48
    protected function extractRootFields(array $fields): array



ERROR: MixedOperand - vendor/yiisoft/arrays/src/ArrayableTrait.php:185:32 - Left operand cannot be mixed (see https://psalm.dev/059)
            $result[] = strstr($field . '.', '.', true);

  The type of $field is sourced from here - vendor/yiisoft/arrays/src/ArrayableTrait.php:180:48
    protected function extractRootFields(array $fields): array



ERROR: MixedAssignment - vendor/yiisoft/arrays/src/ArrayableTrait.php:209:29 - Unable to determine the type that $field is being assigned to (see https://psalm.dev/032)
        foreach ($fields as $field) {

  The type of $field is sourced from here - vendor/yiisoft/arrays/src/ArrayableTrait.php:205:47
    protected function extractFieldsFor(array $fields, string $rootField): array



ERROR: MixedArgument - vendor/yiisoft/arrays/src/ArrayableTrait.php:210:33 - Argument 1 of str_starts_with cannot be mixed, expecting string (see https://psalm.dev/030)
            if (str_starts_with($field, "$rootField.")) {

  The type of $field is sourced from here - vendor/yiisoft/arrays/src/ArrayableTrait.php:205:47
    protected function extractFieldsFor(array $fields, string $rootField): array



ERROR: MixedAssignment - vendor/yiisoft/arrays/src/ArrayableTrait.php:236:47 - Unable to determine the type that $definition is being assigned to (see https://psalm.dev/032)
        foreach ($this->fields() as $field => $definition) {

  The type of $definition is sourced from here - vendor/yiisoft/arrays/src/ArrayableTrait.php:76:31
    public function fields(): array



ERROR: MixedAssignment - vendor/yiisoft/arrays/src/ArrayableTrait.php:238:17 - Unable to determine the type that $field is being assigned to (see https://psalm.dev/032)
                $field = $definition;

  The type of $field is sourced from here - vendor/yiisoft/arrays/src/ArrayableTrait.php:76:31
    public function fields(): array



ERROR: MixedAssignment - vendor/yiisoft/arrays/src/ArrayableTrait.php:241:17 - Unable to determine the type of this assignment (see https://psalm.dev/032)
                $result[$field] = $definition;

  The type of $result[$field] is sourced from here - vendor/yiisoft/arrays/src/ArrayableTrait.php:76:31
    public function fields(): array



ERROR: MixedArrayOffset - vendor/yiisoft/arrays/src/ArrayableTrait.php:241:17 - Cannot access value on variable $result[$field] using mixed offset (see https://psalm.dev/031)
                $result[$field] = $definition;


ERROR: MixedAssignment - vendor/yiisoft/arrays/src/ArrayableTrait.php:249:52 - Unable to determine the type that $definition is being assigned to (see https://psalm.dev/032)
        foreach ($this->extraFields() as $field => $definition) {

  The type of $definition is sourced from here - vendor/yiisoft/arrays/src/ArrayableTrait.php:101:36
    public function extraFields(): array



ERROR: MixedAssignment - vendor/yiisoft/arrays/src/ArrayableTrait.php:251:17 - Unable to determine the type that $field is being assigned to (see https://psalm.dev/032)
                $field = $definition;

  The type of $field is sourced from here - vendor/yiisoft/arrays/src/ArrayableTrait.php:101:36
    public function extraFields(): array



ERROR: MixedAssignment - vendor/yiisoft/arrays/src/ArrayableTrait.php:254:17 - Unable to determine the type of this assignment (see https://psalm.dev/032)
                $result[$field] = $definition;

  The type of $result[$field] is sourced from here - vendor/yiisoft/arrays/src/ArrayableTrait.php:101:36
    public function extraFields(): array



ERROR: MixedArrayOffset - vendor/yiisoft/arrays/src/ArrayableTrait.php:254:17 - Cannot access value on variable $result[$field] using mixed offset (see https://psalm.dev/031)
                $result[$field] = $definition;

Removing the dependency to yii-web

ArrayableTrait depends on Linkable and Link from yii-web for toArray():

public function toArray(array $fields = [], array $expand = [], $recursive = true)
{
    $data = [];
    foreach ($this->resolveFields($fields, $expand) as $field => $definition) {
        $attribute = is_string($definition) ? $this->$definition : $definition($this, $field);

        if ($recursive) {
            $nestedFields = $this->extractFieldsFor($fields, $field);
            $nestedExpand = $this->extractFieldsFor($expand, $field);
            if ($attribute instanceof Arrayable) {
                $attribute = $attribute->toArray($nestedFields, $nestedExpand);
            } elseif (is_array($attribute)) {
                $attribute = array_map(
                    function ($item) use ($nestedFields, $nestedExpand) {
                        if ($item instanceof Arrayable) {
                            return $item->toArray($nestedFields, $nestedExpand);
                        }
                        return $item;
                    },
                    $attribute
                );
            }
        }
        $data[$field] = $attribute;
    }

    if ($this instanceof Linkable) {
        $data['_links'] = Link::serialize($this->getLinks());
    }

    return $recursive ? ArrayHelper::toArray($data) : $data;
}

As far as I know, this is a hack only used by REST, and could be moved to \yii\rest\Serializer::serializeModel(), as an additional $field

Am I missing something?

RFE: ArrayHelper::remove not support array key

We have very usefull methods in ArrayHelper:

/** @param string|\Closure|array $key key name of the array element, an array of keys or property name of the object */
public static function getValue($array, $key, $default = null);

/** @param string|array|null $path the path of where do you want to write a value to `$array` */
public static function setValue(&$array, $path, $value);

The key, path arguments support array type.
But in "remove" method, support of array type of key is missing, which is not fully.

/** @param string $key key name of the array element */
public static function remove(&$array, $key, $default = null);

Please, rewrite remove method to support array type of key.

In some cases don't work ReverseBlockMerge modificator in merge method

What steps will reproduce the problem?

$a = ['A', 'B'];
$b = ['C', 'D', ReverseBlockMerge::class => new ReverseBlockMerge()];
$c = ['X'];
$result = ArrayHelper::merge($a, $b, $c);

What is the expected result?

['C', 'D', 'A', 'B', 'X']

What do you get instead?

['A', 'B', 'C', 'D', 'X']

Change namespace to Yii\Arrays

I think we need to change namespace to Yii\Arrays. That would allow us adding more classes to the package that won't be helpers.

Change result ArrayHelper::getValue().

What steps will reproduce the problem?

I have the following object of a query:

Yiisoft\ActiveRecord\Tests\Stubs\Order#1
(
    [Yiisoft\ActiveRecord\BaseActiveRecord:attributes] => [
        'id' => 1
        'customer_id' => 1
        'created_at' => 1325282384
        'total' => '110'
    ]
    [Yiisoft\ActiveRecord\BaseActiveRecord:oldAttributes] => [
        'id' => 1
        'customer_id' => 1
        'created_at' => 1325282384
        'total' => '110'
    ]
    [Yiisoft\ActiveRecord\BaseActiveRecord:related] => [
        'customer' => Yiisoft\ActiveRecord\Tests\Stubs\Customer#2
        (
            [status2] => null
            [sumTotal] => null
            [Yiisoft\ActiveRecord\BaseActiveRecord:attributes] => [
                'id' => 1
                'email' => '[email protected]'
                'name' => 'user1'
                'address' => 'address1'
                'status' => 1
                'profile_id' => 1
            ]
            [Yiisoft\ActiveRecord\BaseActiveRecord:oldAttributes] => [
                'id' => 1
                'email' => '[email protected]'
                'name' => 'user1'
                'address' => 'address1'
                'status' => 1
                'profile_id' => 1
            ]
            [Yiisoft\ActiveRecord\BaseActiveRecord:related] => []
            [Yiisoft\ActiveRecord\BaseActiveRecord:relationsDependencies] => []
        )
    ]
    [Yiisoft\ActiveRecord\BaseActiveRecord:relationsDependencies] => []
)

With the current method I cannot recover customer, since of course it is not a property and therefore does not iterate and return null.

if (strpos($key, '.') !== false) {
    foreach (explode('.', $key) as $part) {
        if (is_array($array)) {
            if (!array_key_exists($part, $array)) {
                return $default;
            }
            $array = $array[$part];
        } elseif (is_object($array)) {
            if (!property_exists($array, $part)) {
                return $default;
            }
            $array = $array->$part;
        }
    }

    return $array;
}

Previous method: It allowed the object to be iterated, recovering the propierty.

if (strpos($key, '.') !== false) {
    foreach (explode('.', $key) as $part) {
        if (!array_key_exists($part, $array)) {
            return $default;
        }
        $array = $array[$part];
    }
    return $array;
}

Off course \array_key_exist is deprecated for object, change for isset its work.

What is the expected result?

ArrayHelper::getValue($object, 'customer.id') return 1.

Additional info

Q A
Version 3.0
PHP version 7.4
Operating system Windows 10

FR: ArrayHelper::index, remove key from array

Would this be useful? A 4th option for ArrayHelper::index which specifies the key should be removed from the array.
Helps avoid some duplication of data. I can do PR and tests if it's likely to be used.

$array = [
  ['id' => '123', 'data' => 'abc', 'device' => 'laptop'],
  ['id' => '345', 'data' => 'def', 'device' => 'tablet'],
  ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone'],
];
$result = ArrayHelper::index($array, 'id');
[
 '123' => ['id' => '123', 'data' => 'abc', 'device' => 'laptop'],
 '345' => ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone']
]
$result = ArrayHelper::index($array, 'id', [], true);
[
  '123' => ['data' => 'abc', 'device' => 'laptop'],
  '345' => ['data' => 'hgi', 'device' => 'smartphone']
]

Extend the functionality of setValue

How do you like the idea of extending the functionality of setValue by adding an append parameter or similar?
Example:

$arr = [
    'вот' => [
        'мой' => [
            'ключ' => null,
        ],
    ],
];

$result = \Yiisoft\Arrays\ArrayHelper::getValue($arr, ['вот', 'мой', 'ключ'], []);
echo $result; // [];

\Yiisoft\Arrays\ArrayHelper::setValue($arr, ['вот', 'мой', 'ключ'], 'lol');
\Yiisoft\Arrays\ArrayHelper::setValue($arr, ['вот', 'мой', 'ключ'], 'kek');

$result = \Yiisoft\Arrays\ArrayHelper::getValue($arr, ['вот', 'мой', 'ключ'], []);
echo $result; // 'kek';

And adding append

\Yiisoft\Arrays\ArrayHelper::setValue($arr, ['вот', 'мой', 'ключ'], 'lol', append: true);
\Yiisoft\Arrays\ArrayHelper::setValue($arr, ['вот', 'мой', 'ключ'], 'kek', append: true);

$result = \Yiisoft\Arrays\ArrayHelper::getValue($arr, ['вот', 'мой', 'ключ'], []);
echo $result; // ['lol', 'kek'];

If the key does not exist an empty array is initialized.

ArrayHelper::merge for simple arrays

What steps will reproduce the problem?

$arr1 = ['2019-01-25'];
$arr2 = ['2019-01-25'];
$arr3 = ['2019-01-25'];

$data = ArrayHelper::merge($arr1, $arr2, $arr3);

What is the expected result?

[
     '2019-01-25'
]

What do you get instead?

[
     '2019-01-25',
     '2019-01-25',
     '2019-01-25'
]

Additional info

Q A
Version dev-master
PHP version 7.3
Operating system Win7

ArrayHelper::getValue

Hi there! I wanted to propose, as an alternative, to make the third parameter (default) of this function a callback. This would be useful if the default value is necessary, for example, to be obtained from the database or in some other difficult way. I do not suggest changing the API. I want the function to support this parameter with both value and callback. If a calback is transmitted, it will be called to get the value, otherwise it will be used as a value.

BC breaking in ArrayHelper::getValue()

The latest commit to BaseArrayHelper::getValue() yiisoft/yii2@e963b2a that introduced Exceptions can bring too much pain for developers during update to 2.0.11.

  1. People simply do not read every line of documentation, therefore nobody codes try/catch blocks around each ArrayHelper::getValue() just to be on the safe side.
  2. Method getValue() is frequently used in different methods of Yii core. When you use some method, you will never know that execution may can cause an exception because of getValue(). E.g.: ArrayHelper::multisort(['a', 'b', 'c'], 0) throws exception after the commit. This case is not covered with unit tests, of course :)
  3. Method may be used to get default value of something, e.g.: ArrayHelper::getValue(null, 'foo', 'bar') - pretty expected to get bar.

Considering aforementioned, I vote for reverting of this commit.

Problem with support float as keys

Functions getValue, getValueByPath, setValue, setValueByPath, remove support key as float and cast float to string.

Function index replace in float values , to ..

This will work differently depending on PHP settings:

It can potentially cause problems in some cases with non-standard PHP settings.

Maybe remove support float keys in getValue, getValueByPath, setValue, setValueByPath, remove and remove replace , to , for float values in index ?

Inconsistency between ArrayHelper functions

What steps will reproduce the problem?

$arr=['a.b' => ['c' => 'value1', 'd.e' => "value2"]];
ArrayHelper.getValue($arr, 'a.b.c'); //this will return value1
ArrayHelper.setValue($arr, 'a.b.c', 'newValue');
ArrayHelper.getValue($arr, 'a.b.c'); //this will still return value1
ArrayHelper.keyExists('a.b.c', $arr,); //false
ArrayHelper.remove($arr, 'a.b.c'); //this wont work but is currently worked on in #168 

/*
$arr = [
  'a' => [
    'b' => [
      'c' => 'newValue',
    ],
  ],
  'a.b' => [
    'c' => 'value1',
   'd.e' => 'value2', // unreachable with dot syntax
  ]
]*/

What is the expected result?

Using the same key for any function in ArrayHelper (getValue, setValue, remove, keyExists) should result in accessing the same key.

What do you get instead?

Different behavior depending on which function you are using.

Additional info

Q A
Yii version 3.0@dev
PHP version 7.1
Operating system Debian 9

add parameter `expandEnvelope` to `yii\base\Arrayable:toArray()` method

HAL draft 8 mentions that embedded information such as the information defined by Arrayable:extraFields() must go inside a _embedded envelope. Currently there is no way to do it on the methodyii\base\Arrayable:toArray() so i propose to change its signature to

toArray ( array $fields = [], array $expand = [], $recursive = true, $expandEnvelope = '')

by default $expandEnvelope will be empty so it won't produce any envelope and the extra data will be attached as it is done right now.

that way the _embedded property can be created by just invoking it like this

$model->toArray($fields, $extraFields, true, '_embedded');

BC Break

The obvious bc break is the change of the signature for anyone who has extended this method.

other than that any code previously written will behave the same so it won't have any imcompatibility.

array_key_exists is deprecated with objects PHP 7.4 error PhpUnit 9.0.1.

https://wiki.php.net/rfc/deprecations_php_7_4

Change:

if (is_array($array) && array_key_exists((string)$key, $array)) {

For:

if (is_array($array) && isset($array[$key])) {
    return $array[$key];
}

if (!array_key_exists($part, $array)) {

For:

if (strpos($key, '.') !== false) {
    foreach (explode('.', $key) as $part) {
        if (!isset($array[$part])) {
            return $default;
        }
        $array = $array[$part];
    }
    return $array;
}

Unexpected default value

$array = [
    'a' => 1
];
$key = ['a', 'b', 'c'];
$default =[
    'c' => 'value'
];
$result = ArrayHelper::getValue($array, $key, $default);
// $result is "$value"

I think the result should be ['c' => 'value'], right?

ArrayHelper::multisort: remove support use \Closure with return multiple keys

Use \Closure which returning the values for comparison purposes is fine.

But use \Closure which returning array of keys for sorting (test) is too much.

If keys for sorting dependencied by array, then user should get this keys before run multisort.


$array = [
	['name' => 'a', 'age' => 3],
	['name' => 'b', 'age' => 2],
	['name' => 'B', 'age' => 4],
	['name' => 'A', 'age' => 1],
];
ArraySorter::multisort($array, fn ($item) => ['age', 'name'], SORT_DESC);

Now this code is working. Anonymous function for get columns for sort executed for ALL items of array, then used result only first run.

I suggest remove this opportunity. Anonymous function should use only for returning the values for comparison purpose.

ArrayableTrait::toArray incorrectly work with nested arrays

What steps will reproduce the problem?

class Test implements ArrayableInterface
{
    use ArrayableTrait;

    public array $a = [
        'b' => 1,
        'c' => 2,
    ];
}

$object = new Test();
$object->toArray(['a.b'])

What is the expected result?

[
	'a' => [
		'b' => 1,
	],
]

What do you get instead?

[
	'a' => [
		'b' => 1,
		'c' => 2,
	],
]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.