andydune/array-container

它有利于更好地访问值。它支持任何过滤器和转换器。

v1.19.1 2020-03-12 11:48 UTC

README

Build Status Software License Packagist Version Total Downloads

它为封装数组提供方便的接口。实现了任何数量过滤器的策略模板。

要求

  • PHP版本 >= 7.1
  • 在你的耳机里听到“可能是我的问题”。

安装

使用composer安装

composer require andydune/array-container

或者如果全局未安装composer

php composer.phar require andydune/array-container

或者编辑你的composer.json

"require" : {
     "andydune/array-container": "^1"
}

然后执行命令

php composer.phar update

简单访问数组

你不需要担心任何键的存在。

use AndyDune\ArrayContainer\ArrayContainer;

$aray = new ArrayContainer(['pipe' => 'handemade', 'pipes_type' => ['lovat', 'canadian']]);
$array['pipe'] // value is 'handemade' 
$array['tobacco'] // value is null
$array->getNested('pipes_type.0')  // value is 'lovat'
$array->getNested('pipes_type:0', null, ':')  // value is 'lovat'
$array->getNested('some.some', 'NO')  // value is 'NO'

// Set default value
$array->setDefaultValue('NO');
$array['tobacco'] // value is 'NO'

过滤器

过滤器是可调用的对象。过滤器在请求属性时使用getter。

use AndyDune\ArrayContainer\ArrayContainer;
$aray = new ArrayContainer(['pipe' => 'handemade', 'pipes_type' => ['lovat', 'canadian']]);
$array->addFilter(function ($value) {
    return strtoupper($value);
});
$array['pipe'] // value is 'HANDEMADE'

转换器

转换器是实现AndyDune\ArrayContainer\Action\AbstractAction接口的类的对象。它可以简单扩展而不修改主类。

如果不存在则向数组中添加键。

存在源数组

$array = [
    'type' => 'good'
];

你需要在模型中使用它。模型等待具有键:typekeyvalue的数组

use AndyDune\ArrayContainer\ArrayContainer;
use AndyDune\ArrayContainer\Action\KeysAddIfNoExist;
$container = new ArrayContainer();

$defaultValue = 0; // Set this value if array key does not exist.

$container->setAction(new KeysAddIfNoExist($defaultValue))->executeAction('type', 'key', 'value');
$resultArray = $container->getArrayCopy();

结果数组是

$resultArray = [
    'type' => 'good',
    'key' => 0,
    'value' => 0
];

保持键到数据相关性的数组偏移。

这是具有数字键的源数组。

$arraySource = [
    40 => 'fourty',
    50 => 'figty',
    60 => 'sixty',
];

在执行函数array_shift后,键将丢失。

array_shift($arraySource);
$arraySource = [
    0 => 'figty',
    1 => 'sixty',
];

数组容器动作有助于避免这种情况。

use AndyDune\ArrayContainer\ArrayContainer;
use AndyDune\ArrayContainer\Action\ArrayShift;

$arraySource = [
    40 => 'fourty',
    50 => 'figty',
    60 => 'sixty',
];

$container = new ArrayContainer($arraySource);

$result = $container->setAction(new ArrayShift())->executeAction();

$result == [40 => 'fourty'];

$resultArray =  $container->getArrayCopy();

结果数组是

[
    50 => 'figty',
    60 => 'sixty',
];

向嵌套数组添加值

我们有我们不知道结构的数组。需要设置值到它的嵌套值,并检查嵌套结构的是否存在。它只更改给定的数组键。

// Sourse array:
$array = [
    'a' => 1,
    'b' => [
        'c' => 2
    ]
];
$container->setAction(new SetValueIntoNestedArray(22))->executeAction('b', 'cc');
$arrayResult = $container->getArrayCopy();

// Result array is:
$arrayResult = [
    'a' => 1,
    'b' => [
        'c' => 2,
        'cc' => 22
    ]
];

更多示例。

我们有包含月份、年份和该日期内实体数量的静态数组。

$data = [[
    'month' => 7,
    'year' => 2020,
    'orderCount' => 2,
    ],
],
[
    'month' => 1,
    'year' => 2020,
    'orderCount' => 20,
    ],
],

...
]

我们需要得到如下内容

$result = [
    2007 => [
        1 => 2,
        7 => 20
    ]
]

这是此代码

use AndyDune\ArrayContainer\Action\SetValueIntoNestedArray;
use AndyDune\ArrayContainer\ArrayContainer;

$arrayContainer = new ArrayContainer();
foreach($data as $row) {
    $arrayContainer->setAction(new SetValueIntoNestedArray($row['orderCount']))
        ->executeAction($row['year'], $row['month']);
}
$result = $arrayContainer->getArrayCopy();

从数组中移除重复值

需要简单移除重复值。以下是我们可以这样做的方法。

use AndyDune\ArrayContainer\ArrayContainer;
use AndyDune\ArrayContainer\Action\RemoveDuplicates;

$array = [
    'a' => 'a',
    'b' => 'b',
    'b1' => 'b',
    'c' => 'c',
];
$container = new ArrayContainer($array);
$count = $container->setAction(new RemoveDuplicates())->executeAction();
$count == 1; // it is count of removed items
$array = $container->getArrayCopy());

$array; // it has no value with key b1

检查值是否在嵌套数组中

存在具有任何结构的嵌套值。它检查给定的数组中是否有某个值,包括嵌套数组中的值。

use AndyDune\ArrayContainer\ArrayContainer;
use AndyDune\ArrayContainer\Action\InNestedArray;

$array = [
    'a' => 1,
    'b' => [
        'c' => 2
    ]
];
$container = new ArrayContainer($array);
$container->setAction(new InNestedArray(1))->executeAction(); // true
$container->setAction(new InNestedArray('1'))->executeAction(); // true
$container->setAction(new InNestedArray(5))->executeAction(); // false

// With strong type comparision
$container->setAction(new InNestedArray('1', true))->executeAction(); // false

值可以在比较之前更改

$array = [
    [
        [
            'name' => 'Ivan'
        ],
        [
            'name' => 'Andrey'
        ],
    ]
];
$container = new ArrayContainer($array);

// false: Ivan != ivan
$container->setAction(new InNestedArray('ivan'))->executeAction(); 

// true: strtolower to values before compare
$container->setAction((new InNestedArray('ivan'))->setValueMutator(function($value){
    if (!is_string($value)) {
        return $value;
    }
    return strtolower($value);
}))->executeAction();

从当前数组创建新数组中的值

需要从任何固定的列表中创建新值的列表。新列表必须包含随机值。

use AndyDune\ArrayContainer\ArrayContainer;
use AndyDune\ArrayContainer\Action\ExtractRandomItems;

$array = [
    'a',
    'b',
    'c',
    'd',
    'e',
    'f'
];
$container = new ArrayContainer($array);
$arrayNew = $container->setAction(new ExtractRandomItems(3))->executeAction();

它保留新数组中的键,就像在源数组中一样。

连接数组

array_merge函数可能对关联数组不起作用。

以下是一个示例

$a1 = ['first' => 1, 'second' => 2];
$ar = array_merge($a1, ['second' => 22])

The result is:
$ar == ['first' => 1, 'second' => 22];

连接操作有助于正确执行此操作

use AndyDune\ArrayContainer\ArrayContainer;
use AndyDune\ArrayContainer\Action\Concat;

$a1 = ['first' => 1, 'second' => 2];

$container = new ArrayContainer($a1);
$result = $container->setAction(new Concat())->executeAction(['second' => 22]);

The result is:
$ar == ['first' => 1, 'second' => 2, 22];

计算具有附加索引检查的数组之间的差异

将array1与array2及更多进行比较,并返回差异。它递归地计算数组。

use AndyDune\ArrayContainer\ArrayContainer;
use AndyDune\ArrayContainer\Action\ComputeDifferenceOfArrays;

$arrayWait = [
    'r' => 'red',
    'rr' => [
        'r1' => 'red1',
        'rrr' => [
            'r2' => 'red2',
            'r22' => ['red22']
        ],
        'r2' => 'red2',
    ],
    'b' => 'blue'
];

$container = new ArrayContainer($array);
$result = $container->setAction(new ComputeDifferenceOfArrays())->executeAction(
    ['r' => 'red', 'rr' => ['r1' => 'red1', 'rrr' => ['r22' => ['red22']]]]
);

// The resu is:

$arrayWait = [
    'rr' => [
        'rrr' => [
            'r2' => 'red2',
            'r22' => ['red22']
        ],
        'r2' => 'red2',
    ],
    'b' => 'blue'
];

它可能忽略结果中的某些键。

$container = new ArrayContainer($array);
$result = $container->setAction(
(new ComputeDifferenceOfArrays())->ignoreKeys('r2', ['b'])))->executeAction(
    ['r' => 'red', 'rr' => ['r1' => 'red1']]
);

// The resu is:

$arrayWait = [
    'rr' => [
        'rrr' => [
            'r22' => ['red22']
        ],
    ]
];

检查数组是否只有固定键

它检查源数组是否只有这些键。

$array = [
    'r' => 'red',
    'rr' => [
        'r1' => 'red1',
    ],
    'b' => 'blue'
];
$container = new ArrayContainer($array);
$result = $container->setAction(new IsOnlyThisKeysInArray())->executeAction('r');
$result == false;

$container = new ArrayContainer($array);
$result = $container->setAction(new IsOnlyThisKeysInArray())->executeAction('r', ['rr']);
$result == false;

$container = new ArrayContainer($array);
$result = $container->setAction(new IsOnlyThisKeysInArray())->executeAction('r', ['rr', 'b']);
$result == true;

创建具有非序列值值的整数数组

有一个包含整数值的数组。值是混合的,没有顺序,可能重复。我们可以得到跳过的值的数组。

use AndyDune\ArrayContainer\ArrayContainer;
use AndyDune\ArrayContainer\Action\GetIntegerNumbersNotInSequence;

$array = [5, 1, 7, 8];
$container = new ArrayContainer($array);
$result = $container->setAction(new GetIntegerNumbersNotInSequence())->executeAction();
// result is:
[2,3,4,6] == $result;

在数组中查找最大浮点值

它搜索给定数组中的最大浮点值。每个值通过删除空格来准备。

use AndyDune\ArrayContainer\ArrayContainer;
use AndyDune\ArrayContainer\Action\FindMaxFloatValue;

$container = new ArrayContainer(['- 1', -2.56, 10, ' 1 1 ']);
$result = $container->setAction(new FindMaxFloatValue())->executeAction();
$this->assertEquals(11, $result);
// result is:
11 == $result;

使用路径表示法访问数组

访问数组值(如果数组是嵌套的,则更多)可能需要验证和检查。路径有助于使其变得容易。

use AndyDune\ArrayContainer\Path;
$arr = [
'key1' => 'bum',
'key2' => ['key21' => [
    'key211' => 'mub'
]],
];

// To get value with key `key211` you need:
$arr['key2']['key21']['key211'] // mub
// with Path 
$arrObject = new Path($arr);
(string)$arr->key2->key21->key211; // mub

在嵌套数组中设置值

use AndyDune\ArrayContainer\Path;
$arrObject = new Path($arr);
$arr->key2->key21->key211 = 'bum';
 
(string)$arr->key2->key21->key211; // 'bum'
$arr->key2->key21->noExist_id->getValue(); // null

构建数组

MultilineTextToAssociatedArray

它从具有行作为键值对的文本创建数组。

use AndyDune\ArrayContainer\Builder;
use AndyDune\ArrayContainer\BuilderStrategy\MultilineTextToAssociatedArray;

$sourceText = '
one => two
three
=> four

';

$expectResult = [
    'one' => 'two',
    'four',
    'three' => null
];

$builder = new Builder($sourceText, new MultilineTextToAssociatedArray('=>'));

// result is
$expectResult == $builder->execute();

MultilineTextAsJsonToAssociatedArray

它从具有行作为类似于JSON的键值对的文本创建数组。

use AndyDune\ArrayContainer\Builder;
use AndyDune\ArrayContainer\BuilderStrategy\MultilineTextAsJsonToAssociatedArray;

$text = '
{
"one":"two",
"two" : 2,
"three":null
}

';

$expectResult = [
    'one' => 'two',
    'two' => 2,
    'three' => null
];

$builder = new Builder($text, new MultilineTextAsJsonToAssociatedArray());
// result is

$expectResult ==  $builder->execute();

MarkdownTableToArray

它从Markdown表格中创建数组。

了解格式请参阅这里

use AndyDune\ArrayContainer\Builder;
use AndyDune\ArrayContainer\BuilderStrategy\MultilineTextAsJsonToAssociatedArray;

$text = '
| one | two | 
| --- | ---
1 | 2
11
| 12| 13 | 14
';

$expectResult = [
    [
        'one' => 1,
        'two' => 2
    ],
    [
        'one' => '11',
        'two' => null
    ],
    [
        'one' => '12',
        'two' => '13'
    ]
];

$builder = new Builder($text, new MarkdownTableToArray());
$expectResult == $builder->execute();

您可以使用以下方式构建非关联数组

use AndyDune\ArrayContainer\Builder;
use AndyDune\ArrayContainer\BuilderStrategy\MultilineTextAsJsonToAssociatedArray;

$text = '
    | one | two | 
    1 | 2
    |
    || 5
    11
    | 12| 13 | 14
';

$expectResult = [
    ['one', 'two'],
    [1, 2],
    ['', 5],
    ['11',  null],
    ['12', '13']
];

$builder = new Builder($text, new MarkdownTableToArray());
$expectResult == $builder->execute();

MultilineTextToNestedAssociatedArray

它从具有行作为键值对的文本中创建数组。值是嵌套数组。

use AndyDune\ArrayContainer\Builder;
use AndyDune\ArrayContainer\BuilderStrategy\MultilineTextToNestedAssociatedArray;

$text = '
one > one, 
one > two, one
four > 4, 5, 6
';

$expectResult = [
    'one' => ['one', 'two'],
    'four' => [4, 5, 6],
];

$builder = new Builder($text, new MultilineTextToNestedAssociatedArray());
$expectResult == $builder->execute();

StringExplode

它执行简单的字符串拆分过程,可选删除空值或保留。

use AndyDune\ArrayContainer\Builder;
use AndyDune\ArrayContainer\BuilderStrategy\StringExplode;

$text = '
    one , two,
';

$expectResult = [
    'one', 'two'
];

$builder = new Builder($text, new StringExplode(','));
$expectResult == $builder->execute();