From c5a3f28fad4e379bd305085fc2c28e8df450c6a2 Mon Sep 17 00:00:00 2001 From: Kunal Mehta Date: Mon, 9 Oct 2017 15:22:48 -0700 Subject: [PATCH] Dict\flatten Summary: Adding for parity with `{Keyset, Vec}\flatten`. Reviewed By: fredemmott Differential Revision: D6011560 fbshipit-source-id: 3527e9e5358a6795242f56dc5dd6ffe34e4a9cad --- src/dict/combine.php | 8 +--- src/dict/transform.php | 19 ++++++++ tests/dict/DictTransformTest.php | 77 ++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 7 deletions(-) diff --git a/src/dict/combine.php b/src/dict/combine.php index 2b12ecc5..d4addf49 100644 --- a/src/dict/combine.php +++ b/src/dict/combine.php @@ -41,11 +41,5 @@ function associate( function merge( KeyedTraversable ...$traversables ): dict { - $result = dict[]; - foreach ($traversables as $traversable) { - foreach ($traversable as $key => $value) { - $result[$key] = $value; - } - } - return $result; + return namespace\flatten($traversables); } diff --git a/src/dict/transform.php b/src/dict/transform.php index c2dd018d..0c75486c 100644 --- a/src/dict/transform.php +++ b/src/dict/transform.php @@ -47,6 +47,25 @@ function count_values( return $result; } +/** + * Returns a new dict formed by merging the KeyedTraversable elements of the + * given Traversable. In the case of duplicate keys, later values will overwrite + * the previous ones. + * + * For a fixed number of KeyedTraversables, see `Dict\merge`. + */ +function flatten( + Traversable> $traversables, +): dict { + $result = dict[]; + foreach ($traversables as $traversable) { + foreach ($traversable as $key => $value) { + $result[$key] = $value; + } + } + return $result; +} + /** * Returns a new dict where all the given keys map to the given value. */ diff --git a/tests/dict/DictTransformTest.php b/tests/dict/DictTransformTest.php index 5c9538b3..cb0ad4b8 100644 --- a/tests/dict/DictTransformTest.php +++ b/tests/dict/DictTransformTest.php @@ -136,6 +136,83 @@ public function testFillKeys( expect(Dict\fill_keys($keys, $value))->toBeSame($expected); } + public static function provideTestFlatten(): array { + return array( + tuple( + array(), + dict[], + ), + tuple( + array( + array( + 'one' => 'one', + 'two' => 'two', + ), + array( + 'three' => 'three', + 'one' => 3, + ), + Map { + 'four' => null, + }, + ), + dict[ + 'one' => 3, + 'two' => 'two', + 'three' => 'three', + 'four' => null, + ], + ), + tuple( + array( + HackLibTestTraversables::getKeyedIterator(array( + 'foo' => 'foo', + 'bar' => 'bar', + 'baz' => array(1, 2, 3), + )), + dict[ + 'bar' => 'barbar', + ], + Vector {'I should feel bad for doing this', 'But yolo'}, + array( + '1' => 'gross array behavior', + ), + Set {'bloop'}, + ), + dict[ + 'foo' => 'foo', + 'bar' => 'barbar', + 'baz' => array(1, 2, 3), + 0 => 'I should feel bad for doing this', + 1 => 'gross array behavior', + 'bloop' => 'bloop', + ], + ), + tuple( + HackLibTestTraversables::getIterator(array( + vec['zero'], + array(1 => 'one'), + dict[2 => 'two'], + Map {3 => 'three'}, + )), + dict[ + 0 => 'zero', + 1 => 'one', + 2 => 'two', + 3 => 'three', + ], + ), + ); + } + + /** @dataProvider provideTestFlatten */ + public function testFlatten( + Traversable> $traversables, + dict $expected, + ): void { + expect(Dict\flatten($traversables))->toBeSame($expected); + } + public static function provideTestFlip(): array { return array( tuple(