charm/map

类似于 JavaScript 中的 Map 的哈希表实现 - 允许使用任何数据类型作为键和值。一个小巧、全面且高效的哈希表实现。

1.0.5 2021-12-21 08:07 UTC

This package is auto-updated.

Last update: 2024-09-21 14:08:43 UTC


README

Map 是 PHP 中最缺乏的重要数据结构之一。高性能的 Map 非常复杂,你并不能每次真正需要它时都“临时拼凑”出来,与简单的数组扫描相比,速度非常慢。

  • 任何类型的键 - 对象、数组、布尔值甚至是 null
  • 任何类型的值。
  • “模板类型模拟”:使用 $map = Map::T([ 'string', 'int' ]) 可以创建 Map<string, int>
  • 可计数:count($map)
  • 可迭代:foreach ($map as $key => $value) {}
  • 隐式项目创建:即使 'newKey' 不存在,$map['newKey'][] = "Value"; 也不会触发警告。

它解决的问题取决于你。它允许你将任何 PHP 值与任何其他 PHP 值相关联,在构建图、缓存和检测树结构中的循环递归时非常有用。

数组固有的问题

// various types are converted to int
$array[1.23] = "Foo";       // actual value: [ 1 => "Foo" ]
$array[true] = "Foo";       // actual value: [ 1 => "Foo" ]
$array[null] = "Foo";       // actual value: [ "" => "Foo" ]

// Other types are fatal errors
$array[ [1,2,3] ];          // PHP Fatal error:  Illegal offset type
$array[ $user ];            // PHP Fatal error:  Illegal offset type
$array[ tmpfile() ];        // PHP Fatal error:  Illegal offset type

快速开始

$first = ["some array"];
$second = (object) ["prop" => "another array"];
$third = null;

$map = new Charm\Map();

// Any key
$map['hello'] = 'World';
$map[$first] = 'hello';
$map[$second] = $first;
$map[$third] = $map;

// Implicit value creation
$map['undefined key'][] = 1;    // 'undefined key' does not exist, but appending works
$map['undefined key'][] = 2;    // 'undefined key' is no longer undefined

// Iteratble
foreach ($map as $key => $value) {
}

// Countable
echo "Map has {count($map)} elements\n";

Map 与 PHP 内置数组不同,你可以使用任何值作为键。普通数组不允许你使用浮点数、资源指针或对象作为键。

朋友的朋友遍历示例(FOAF)

$friends = new Map();
$friends[$user_A][$user_B] = 1;                   // register all current friendships
$friends[$user_A][$user_C] = 1;
$friends[$user_B][$user_C] = 1;                   
$friends[$user_B][$user_D] = 1;                   // only $user_B is friend with $user_D

// traverse friends of friends graph
foreach ( $friends[$user_A] as $friend_1 => $distance_1) {

    foreach ($friends[$friend] as $friend_2 => $distance_2) {

        if ( $user_A === $friend_2 ) {
            // ignore friendships back to myself
        } elseif ( isset( $friends[$user_A][$friend_2] ) ) {
            // i am already a friend
        } else {
            echo "$friend_2 is a friend of a friend to you!\n";
        }
    }
}

注意事项

对于 PHP 中的标量(整数、字符串、布尔值和数组)值,用作键的是 字面值。如果你使用数组作为键,然后修改该数组 - 可能找不到值。

$secretKey1 = ['foo'];
$secretKey2 = ['foo','bar'];

$map[$secretKey1] = "Important data";
$map[$secretKey2] = "Sensitive matters"

$secretKey1[] = 'bar';  // oops! You've modified $secretKey1 and you can't find "Important data" any more.

echo $map[$secretKey1]; // 'Sensitive matters' turns out it became identical to $secretKey2

你应该避免使用数组作为键;由于哈希,它们是速度最慢的键类型。