3 * Copyright (c) 2004-present, Facebook, Inc.
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
11 namespace HH\Lib\Keyset
;
13 use namespace HH\Lib\C
;
16 * Returns a new keyset containing only the elements of the first Traversable
17 * that do not appear in any of the other ones.
19 * Time complexity: O(n + m), where n is size of `$first` and m is the combined
20 * size of `$second` plus all the `...$rest`
21 * Space complexity: O(n + m), where n is size of `$first` and m is the combined
22 * size of `$second` plus all the `...$rest` -- note that this is bigger than
25 function diff
<Tv1
as arraykey
, Tv2
as arraykey
>(
26 Traversable
<Tv1
> $first,
27 Traversable
<Tv2
> $second,
28 Container
<Tv2
> ...$rest
33 if (!$second && !$rest) {
34 return keyset($first);
36 $union = !$rest ?
keyset($second) : union($second, ...$rest);
37 return filter($first, $value ==> !C\
contains_key($union, $value));
40 * Returns a new keyset containing all except the first `$n` elements of
41 * the given Traversable.
43 * To take only the first `$n` elements, see `Keyset\take()`.
45 * Time complexity: O(n), where n is the size of `$traversable`
46 * Space complexity: O(n), where n is the size of `$traversable`
48 function drop
<Tv
as arraykey
>(
49 Traversable
<Tv
> $traversable,
52 invariant($n >= 0, 'Expected non-negative N, got %d.', $n);
55 foreach ($traversable as $value) {
66 * Returns a new keyset containing only the values for which the given predicate
67 * returns `true`. The default predicate is casting the value to boolean.
69 * To remove null values in a typechecker-visible way, see `Keyset\filter_nulls()`.
71 * Time complexity: O(n * p), where p is the complexity of `$value_predicate`
72 * Space complexity: O(n)
74 function filter
<Tv
as arraykey
>(
75 Traversable
<Tv
> $traversable,
76 ?
(function(Tv
)[_
]: bool) $value_predicate = null,
77 )[ctx
$value_predicate]: keyset
<Tv
> {
78 $value_predicate ??
= \HH\Lib\_Private\boolval
<>;
80 foreach ($traversable as $value) {
81 if ($value_predicate($value)) {
89 * Returns a new keyset containing only non-null values of the given
92 * Time complexity: O(n)
93 * Space complexity: O(n)
95 function filter_nulls
<Tv
as arraykey
>(
96 Traversable
<?Tv
> $traversable,
99 foreach ($traversable as $value) {
100 if ($value !== null) {
108 * Returns a new keyset containing only the values for which the given predicate
111 * If you don't need access to the key, see `Keyset\filter()`.
113 * Time complexity: O(n * p), where p is the complexity of `$predicate`
114 * Space complexity: O(n)
116 function filter_with_key
<Tk
, Tv
as arraykey
>(
117 KeyedTraversable
<Tk
, Tv
> $traversable,
118 (function(Tk
, Tv
)[_
]: bool) $predicate,
119 )[ctx
$predicate]: keyset
<Tv
> {
121 foreach ($traversable as $key => $value) {
122 if ($predicate($key, $value)) {
130 * Returns a new keyset containing the keys of the given KeyedTraversable,
131 * maintaining the iteration order.
133 function keys
<Tk
as arraykey
, Tv
>(
134 KeyedTraversable
<Tk
, Tv
> $traversable,
137 foreach ($traversable as $key => $_) {
144 * Returns a new keyset containing only the elements of the first Traversable
145 * that appear in all the other ones.
147 * Time complexity: O(n + m), where n is size of `$first` and m is the combined
148 * size of `$second` plus all the `...$rest`
149 * Space complexity: O(n), where n is size of `$first`
151 function intersect
<Tv
as arraykey
>(
152 Traversable
<Tv
> $first,
153 Traversable
<Tv
> $second,
154 Container
<Tv
> ...$rest
156 if (!$first ||
!$second) {
159 $intersection = keyset($first);
161 foreach ($rest as $traversable) {
162 $next_intersection = keyset
[];
163 $keyed_traversable = keyset($traversable);
164 foreach ($intersection as $value) {
165 if (C\
contains_key($keyed_traversable, $value)) {
166 $next_intersection[] = $value;
169 if (!$next_intersection) {
172 $intersection = $next_intersection;
174 return $intersection;
178 * Returns a new keyset containing the first `$n` elements of the given
181 * If there are duplicate values in the Traversable, the keyset may be shorter
182 * than the specified length.
184 * To drop the first `$n` elements, see `Keyset\drop()`.
186 * Time complexity: O(n), where n is `$n`
187 * Space complexity: O(n), where n is `$n`
189 function take
<Tv
as arraykey
>(
190 Traversable
<Tv
> $traversable,
196 invariant($n > 0, 'Expected non-negative N, got %d.', $n);
199 foreach ($traversable as $value) {