Skip to content

jonnyynnoj/dot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

65 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dot

Travis (.com) Latest Stable Version PHP Version Support License Total Downloads

Dot allows you to get & set array keys or object properties using dot notation.

Installing

composer require noj/dot

Usage

First construct a new Dot instance:

$dot = new Dot($data);
$dot = Dot::from($data); // alternative

All the examples are using the following data structure unless otherwise specified:

$data = [
    'groups' => [
        (object)[
            'name' => 'group1',
            'items' => [
                [
                    'name' => 'item1',
                    'rare' => false,
                ],
                [
                    'name' => 'item3',
                    'rare' => true,
                ],
            ]
        ],
        (object)[
            'name' => 'group2',
            'items' => []
        ],
        (object)[
            'name' => 'group3',
            'items' => [
                [
                    'name' => 'item2',
                    'rare' => true,
                ],
            ]
        ],
    ]
];

Methods

Dot::count(string $path): int

Count the number of items at a given path.

$dot->count('groups.0.items'); // 2
$dot->count('groups.*.items'); // 3

Dot::find(string $path, mixed $equals): Dot

Find items that pass the given truth test.

// find where property === value
$dot->find('groups.*.items.*.rare', true)->get();
/*
[
    ['name' => 'item3', 'rare' => true],
    ['name' => 'item2', 'rare' => true],
]
*/

// pass a callback for custom comparisons 
$dot->find('groups.*.items.*.name', function (string $name) {
    return $name === 'item2' || $name === 'item3';
})->get(); // returns same as above

// leave off the property to receive the whole item
$dot->find('groups.*.items.*', function (array $item) {
    return $item['name'] === 'item3' && $item['rare'];
})->get();

Dot::first(string $path, mixed $equals): Dot

Find the first item that passes the given truth test.

$dot->first('groups.*.items.*.rare', true)->get(); // ['name' => 'item3', 'rare' => true]

$dot->first('groups.*.items.*', function (array $item) {
    return $item['rare'] === true;
})->get(); // same as above

Dot::get(null|int|string $path): mixed

Access nested array keys and object properties using dot syntax:

$dot->get('groups.0.items.1.name'); // 'item3'

Dot safely returns null if the key or property doesn't exist:

$dot->get('groups.3.items.1.name'); // null

You can use a wildcard * to pluck values from multiple paths:

$dot->get('groups.*.items.*.name'); // ['item1', 'item3', 'item2']

$dot->get('groups.*.items'); /* [
    ['name' => 'item1', 'rare' => false],
    ['name' => 'item3', 'rare' => true],
    ['name' => 'item2', 'rare' => true],
] */

You can call functions using the @ prefix:

$data = [
    'foo' => new class {
        public function getBar() {
            return ['bar' => 'value'];
        }
    }
];

(new Dot($data))->get('foo.@getBar.bar'); // 'value'

If no argument is passed it will return the underlying data:

$dot->get() === $data; // true

Dot::has(string $path): bool

Returns true if path exists, false otherwise:

$dot->has('groups.0.items.1.name'); // true

Dot::push(string $path, mixed $value): Dot

Push a value onto an existing array:

$dot->push('groups.0.items', ['name' => 'another item']);

// supports wildcards
$dot->push('groups.*.items', ['name' => 'another item']);

Dot::set(array|string $paths, mixed $value): void

You can set nested values using the same syntax:

$dot->set('groups.2.items.0.name', 'a different name');
echo $data['groups'][2]->items[0]['name']; // 'a different name'

Set nested keys from multiple paths using a wildcard *:

$dot->set('groups.*.items.*.name', 'set all to same name');

Keys will be created if they don't already exist:

$dot->set('groups.0.items.2.name', 'a new item');

By default, set will initialise missing values as empty arrays. To indicate that something should be an object use the -> delimiter:

$dot->set('groups.3->items.2.name', 'a new item');

You can set multiple values at once by passing an array:

$dot->set([
    'groups.0.items.1.name' => 'something',
    'groups.2.items.0.name' => 'something else',
]):

You can call a method:

$data = [
    'foo' => new class {
        public $bars = [];
        public function addBar($bar) {
            $this->bar[] = $bar;
        }
    }
];

$dot = new Dot($data);
$dot->set('foo.@addBar', 'value');
echo $data['foo']->bars; // ['value']

Or call a method for each value of an array:

$dot->set('foo.@addBar*', ['value1', 'value2']);
echo $data['foo']->bars; // ['value1', 'value2']

Non-chained versions

All methods have non-chained versions of themselves as a standalone function, i.e:

// instead of
$filtered = \Noj\Dot\Dot::from($data)
    ->find('groups.*.items.*.rare', true)
    ->get();

// you can do
$filtered = \Noj\Dot\find($data, 'groups.*.items.*.rare', true');

About

Use dot notation to access nested array keys and/or object properties

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages