std.algorithm.comparison
Это подмодуль std.algorithm. Он содержит общие алгоритмы сравнения.
| Имя функции | Описание |
|---|---|
among | Проверяет, является ли значение одним из набора значений, например, if (v.among(1, 2, 3)) // v is 1, 2 or 3
|
castSwitch | (new A()).castSwitch((A a)=>1,(B b)=>2) возвращает 1. |
clamp | clamp(1, 3, 6) возвращает 3. clamp(4, 3, 6) возвращает 4. |
cmp | cmp("abc", "abcd") это -1, cmp("abc", "aba") это 1, а cmp("abc", "abc") это 0. |
either | Возвращает первый параметр p, который проходит тест if (p), например, either(0, 42, 43) возвращает 42. |
equal | Сравнивает диапазоны на равенство элементов попарно, например, equal([1, 2, 3], [1.0, 2.0, 3.0]) возвращает true. |
isPermutation | isPermutation([1, 2], [2, 1]) возвращает true. |
isSameLength | isSameLength([1, 2, 3], [4, 5, 6]) возвращает true. |
levenshteinDistance | levenshteinDistance("kitten", "sitting") возвращает 3, используя алгоритм расстояния Левенштейна. |
levenshteinDistanceAndPath | levenshteinDistanceAndPath("kitten", "sitting") возвращает tuple(3, "snnnsni"), используя алгоритм расстояния Левенштейна. |
max | max(3, 4, 2) возвращает 4. |
min | min(3, 4, 2) возвращает 2. |
mismatch | mismatch("oh hi", "ohayo") возвращает tuple(" hi", "ayo"). |
predSwitch | 2.predSwitch(1, "one", 2, "two", 3, "three") возвращает "two". |
- Лицензия:
- Лицензия Boost 1.0.
- Авторы:
- Андрей Александреску
- Исходный код
- std/algorithm/comparison.d
- uint among(alias pred = (a, b) => a == b, Value, Values...)(Value value, Values values)
Constraints: if (Values.length != 0);
template among(values...) if (isExpressionTuple!values) -
Найти
valueсредиvalues, возвращая индекс первого совпавшего значения вvalues, или0еслиvalueне средиvalues. Предикатpredиспользуется для сравнения значений, по умолчанию используется равенство.- Параметры:
pred Предикат, используемый для сравнения значений. Value valueЗначение, которое нужно найти. Values valuesЗначения, с которыми нужно сравнить искомое значение.
- Возвращает:
- 0, если значение не найдено среди значений, иначе возвращается индекс найденного значения плюс один.
- См. также:
- find и canFind для поиска значения в диапазоне.
- Примеры:
-
assert(3.among(1, 42, 24, 3, 2)); if (auto pos = "bar".among("foo", "bar", "baz")) writeln(pos); // 2 else assert(false); // 42 is larger than 24 writeln(42.among!((lhs, rhs) => lhs > rhs)(43, 24, 100)); // 2
- Примеры:
- В качестве альтернативы,
valuesможет быть передан во время компиляции, что позволяет выполнить более эффективный поиск, но поддерживает только сравнение на равенство:assert(3.among!(2, 3, 4)); writeln("bar".among!("foo", "bar", "baz")); // 2
- auto castSwitch(choices...)(Object switchObject);
-
Выполняет и возвращает один из набора обработчиков, основываясь на типе объекта switch.
Первый вариант, к которому
switchObjectможет быть приведен к типу аргумента, который он принимает, будет вызван сswitchObjectприведённым к этому типу, и возвращаемое им значение будет возвращеноcastSwitch.
Если возвращаемый тип варианта void, вариант должен сгенерировать исключение, если все варианты void. В этом случае castSwitch вернёт void.- Исключения:
- Если ни один из вариантов не соответствует, будет сгенерировано
SwitchError.SwitchErrorтакже будет сгенерировано, если не все варианты void, и void-вариант был выполнен без генерации исключения.
- Параметры:
choices Варианты должны состоять из функций или делегатов-обработчиков, принимающих один аргумент. Также может быть вариант, принимающий ноль аргументов. Этот вариант будет вызван, если switchObjectимеет значение null.Object switchObjectОбъект, с которым выполняются проверки.
- Возвращает:
- Значение выбранного варианта.
- Примечание
-
castSwitchможет быть использован только с объектами.
- Примеры:
-
import std.algorithm.iteration : map; import std.format : format; class A { int a; this(int a) {this.a = a;} @property int i() { return a; } } interface I { } class B : I { } Object[] arr = [new A(1), new B(), null]; auto results = arr.map!(castSwitch!( (A a) => "A with a value of %d".format(a.a), (I i) => "derived from I", () => "null reference", ))(); // A is handled directly: writeln(results[0]); // "A with a value of 1" // B has no handler - it is handled by the handler of I: writeln(results[1]); // "derived from I" // null is handled by the null handler: writeln(results[2]); // "null reference"
- Примеры:
- Использование с void-обработчиками:
import std.exception : assertThrown; class A { } class B { } // Void handlers are allowed if they throw: assertThrown!Exception( new B().castSwitch!( (A a) => 1, (B d) { throw new Exception("B is not allowed!"); } )() ); // Void handlers are also allowed if all the handlers are void: new A().castSwitch!( (A a) { }, (B b) { assert(false); }, )();
- auto clamp(T1, T2, T3)(T1 val, T2 lower, T3 upper)
Constraints: if (is(typeof(max(min(val, upper), lower)))); -
Ограничивает значение заданными пределами.
Эта функция эквивалентна
max(lower, min(upper, val)).- Параметры:
T1 valЗначение, которое нужно ограничить. T2 lowerНижняя граница ограничения. T3 upperВерхняя граница ограничения.
- Возвращает:
- Возвращает
val, если оно находится междуlowerиupper. В противном случае возвращает ближайшее из двух значений.
- Примеры:
-
writeln(clamp(2, 1, 3)); // 2 writeln(clamp(0, 1, 3)); // 1 writeln(clamp(4, 1, 3)); // 3 writeln(clamp(1, 1, 1)); // 1 writeln(clamp(5, -1, 2u)); // 2
- auto cmp(R1, R2)(R1 r1, R2 r2)
Constraints: if (isInputRange!R1 && isInputRange!R2);
int cmp(alias pred, R1, R2)(R1 r1, R2 r2)
Constraints: if (isInputRange!R1 && isInputRange!R2); -
Выполняет лексикографическое сравнение двух входных диапазонов. Итерируя
r1иr2синхронно,cmpсравнивает каждый элементe1изr1с соответствующим элементомe2вr2. Если один из диапазонов закончился,cmpвозвращает отрицательное значение, еслиr1имеет меньше элементов, чемr2, положительное значение, еслиr1имеет больше элементов, чемr2, и0если диапазоны имеют одинаковое количество элементов.Если диапазоны являются строками,
cmpвыполняет соответствующее декодирование UTF и сравнивает диапазоны по одному кодовому элементу за раз.
Можно указать пользовательский предикат, в этом случаеcmpвыполняет лексикографическое сравнение с помощьюpred. В противном случае элементы сравниваются с помощьюopCmp.- Параметры:
pred Предикат, используемый для сравнения. Без указанного предиката используется порядок, подразумеваемый opCmpR1 r1Первый диапазон. R2 r2Второй диапазон.
- Возвращает:
-
0если диапазоны равны. Отрицательное значение, еслиr1является префиксомr2или первый отличающийся элементr1меньше соответствующего элементаr2в соответствии сpred. Положительное значение, еслиr2является префиксомr1или первый отличающийся элементr2меньше соответствующего элементаr1в соответствии сpred.
- Примечание
- В более ранней версии документации неправильно утверждалось, что
-1является единственным возвращаемым отрицательным значением, а1- единственным положительным. Верно ли это, зависит от типов, которые сравниваются.
- Примеры:
-
int result; result = cmp("abc", "abc"); writeln(result); // 0 result = cmp("", ""); writeln(result); // 0 result = cmp("abc", "abcd"); assert(result < 0); result = cmp("abcd", "abc"); assert(result > 0); result = cmp("abc"d, "abd"); assert(result < 0); result = cmp("bbc", "abc"w); assert(result > 0); result = cmp("aaa", "aaaa"d); assert(result < 0); result = cmp("aaaa", "aaa"d); assert(result > 0); result = cmp("aaa", "aaa"d); writeln(result); // 0 result = cmp("aaa"d, "aaa"d); writeln(result); // 0 result = cmp(cast(int[])[], cast(int[])[]); writeln(result); // 0 result = cmp([1, 2, 3], [1, 2, 3]); writeln(result); // 0 result = cmp([1, 3, 2], [1, 2, 3]); assert(result > 0); result = cmp([1, 2, 3], [1L, 2, 3, 4]); assert(result < 0); result = cmp([1L, 2, 3], [1, 2]); assert(result > 0);
- Примеры:
- Пример предиката, который сравнивает отдельные элементы в обратном лексикографическом порядке
int result; result = cmp!"a > b"("abc", "abc"); writeln(result); // 0 result = cmp!"a > b"("", ""); writeln(result); // 0 result = cmp!"a > b"("abc", "abcd"); assert(result < 0); result = cmp!"a > b"("abcd", "abc"); assert(result > 0); result = cmp!"a > b"("abc"d, "abd"); assert(result > 0); result = cmp!"a > b"("bbc", "abc"w); assert(result < 0); result = cmp!"a > b"("aaa", "aaaa"d); assert(result < 0); result = cmp!"a > b"("aaaa", "aaa"d); assert(result > 0); result = cmp!"a > b"("aaa", "aaa"d); writeln(result); // 0 result = cmp("aaa"d, "aaa"d); writeln(result); // 0 result = cmp!"a > b"(cast(int[])[], cast(int[])[]); writeln(result); // 0 result = cmp!"a > b"([1, 2, 3], [1, 2, 3]); writeln(result); // 0 result = cmp!"a > b"([1, 3, 2], [1, 2, 3]); assert(result < 0); result = cmp!"a > b"([1, 2, 3], [1L, 2, 3, 4]); assert(result < 0); result = cmp!"a > b"([1L, 2, 3], [1, 2]); assert(result > 0);
- template equal(alias pred = "a == b")
-
Сравнивает два диапазона на равенство, как определено предикатом
pred(по умолчанию==).- Примеры:
-
import std.algorithm.comparison : equal; import std.math : approxEqual; int[4] a = [ 1, 2, 4, 3 ]; assert(!equal(a[], a[1..$])); assert(equal(a[], a[])); assert(equal!((a, b) => a == b)(a[], a[])); // different types double[4] b = [ 1.0, 2, 4, 3]; assert(!equal(a[], b[1..$])); assert(equal(a[], b[])); // predicated: ensure that two vectors are approximately equal double[4] c = [ 1.005, 2, 4, 3]; assert(equal!approxEqual(b[], c[]));
- Примеры:
- Подсказка:
equalможет использоваться в качестве предиката для других функций. Это может быть очень полезно, когда тип элемента диапазона сам по себе является диапазоном. В частности,equalможет быть собственным предикатом, что позволяет сравнивать диапазоны диапазонов (диапазонов...диапазонов).import std.algorithm.comparison : equal; import std.range : iota, chunks; assert(equal!(equal!equal)( [[[0, 1], [2, 3]], [[4, 5], [6, 7]]], iota(0, 8).chunks(2).chunks(2) ));
- bool equal(Range1, Range2)(Range1 r1, Range2 r2)
Constraints: if (isInputRange!Range1 && isInputRange!Range2 && !(isInfinite!Range1 && isInfinite!Range2) && is(typeof(binaryFun!pred(r1.front, r2.front)))); -
Сравнивает два диапазона на равенство. Диапазоны могут иметь разные типы элементов, если
pred(r1.front, r2.front)вычисляется какbool. Выполняет Ο(min(r1.length, r2.length)) вычисленийpred.По крайней мере один из диапазонов должен быть конечным. Если один из диапазонов бесконечен, результат (статически известен как)
false.
Если два диапазона представляют разные типы кодовых единиц UTF (char,wchar, илиdchar), то массивы сравниваются с использованием декодирования UTF, чтобы избежать случайного повышения целых чисел.- Параметры:
Range1 r1Первый диапазон для сравнения. Range2 r2Второй диапазон для сравнения.
- Возвращает:
-
trueтогда и только тогда, когда два диапазона равны по элементам, согласно бинарному предикатуpred.
- enum EditOp: char;
-
Кодирует операции редактирования, необходимые для преобразования одной последовательности в другую. Даны последовательности
s(источник) иt(цель), последовательностьEditOpкодирует шаги, которые необходимо выполнить для преобразованияsвt. Например, еслиs = "cat"и"cars", минимальная последовательность, преобразующаяsвt: пропустить две буквы, заменить 't' на 'r' и вставить 's'. Работа с операциями редактирования полезна в приложениях, таких как spell-checkers (для поиска ближайшего слова к заданному ошибочному), приближённый поиск, программы типа diff, которые вычисляют разницу между файлами, эффективное кодирование исправлений, анализ последовательностей ДНК и обнаружение плагиата.- Примеры:
-
with(EditOp) { // [none, none, none, insert, insert, insert] writeln(levenshteinDistanceAndPath("foo", "foobar")[1]); // [substitute, none, substitute, none, none, remove] writeln(levenshteinDistanceAndPath("banana", "fazan")[1]); }
- none
-
Текущие элементы равны; редактирование не требуется.
- substitute
-
Заменить текущий элемент в целевой последовательности текущим элементом в исходной последовательности.
- insert
-
Вставить текущий элемент из исходной последовательности в целевую.
- remove
-
Удалить текущий элемент из целевой последовательности.
- size_t levenshteinDistance(alias equals = (a, b) => a == b, Range1, Range2)(Range1 s, Range2 t)
Constraints: if (isForwardRange!Range1 && isForwardRange!Range2);
size_t levenshteinDistance(alias equals = (a, b) => a == b, Range1, Range2)(auto ref Range1 s, auto ref Range2 t)
Constraints: if (isConvertibleToString!Range1 || isConvertibleToString!Range2);
-
Возвращает расстояние Левенштейна между
sиt. Расстояние Левенштейна вычисляет минимальное количество операций редактирования, необходимых для преобразованияsвt. Выполняет Ο(s.length * t.length) вычисленийequalsи занимает Ο(min(s.length, t.length)) памяти.- Параметры:
equals Бинарный предикат для сравнения элементов двух диапазонов. Range1 sИсходный диапазон. Range2 tЦелевой диапазон преобразования.
- Возвращает:
- Минимальное количество правок для преобразования s в t. Не выделяет память GC.
- Примеры:
-
import std.algorithm.iteration : filter; import std.uni : toUpper; writeln(levenshteinDistance("cat", "rat")); // 1 writeln(levenshteinDistance("parks", "spark")); // 2 writeln(levenshteinDistance("abcde", "abcde")); // 0 writeln(levenshteinDistance("abcde", "abCde")); // 1 writeln(levenshteinDistance("kitten", "sitting")); // 3 assert(levenshteinDistance!((a, b) => toUpper(a) == toUpper(b)) ("parks", "SPARK") == 2); writeln(levenshteinDistance("parks".filter!"true", "spark".filter!"true")); // 2 writeln(levenshteinDistance("ID", "I♥D")); // 1
- Tuple!(size_t, EditOp[]) levenshteinDistanceAndPath(alias equals = (a, b) => a == b, Range1, Range2)(Range1 s, Range2 t)
Constraints: if (isForwardRange!Range1 && isForwardRange!Range2);
Tuple!(size_t, EditOp[]) levenshteinDistanceAndPath(alias equals = (a, b) => a == b, Range1, Range2)(auto ref Range1 s, auto ref Range2 t)
Constraints: if (isConvertibleToString!Range1 || isConvertibleToString!Range2); -
Возвращает расстояние Левенштейна и путь редактирования между
sиt.- Параметры:
equals Бинарный предикат для сравнения элементов двух диапазонов. Range1 sИсходный диапазон. Range2 tЦелевой диапазон преобразования.
- Возвращает:
- Кортеж, где первый элемент — минимальное количество правок для преобразования s в t, а второй — последовательность правок для этого преобразования. Выделяет память GC для возвращаемого массива EditOp[].
- Примеры:
-
string a = "Saturday", b = "Sundays"; auto p = levenshteinDistanceAndPath(a, b); writeln(p[0]); // 4 assert(equal(p[1], "nrrnsnnni"));
- auto max(T...)(T args)
Constraints: if (T.length >= 2 && !is(CommonType!T == void)); -
Проходит по переданным аргументам и возвращает максимальное значение.
- Параметры:
T argsЗначения, для которых нужно выбрать максимальное. Должно быть передано как минимум два аргумента, и они должны быть сравнимы с >.
- Возвращает:
- Максимальное из переданных значений. Тип возвращаемого значения — тип среди переданных аргументов, способный хранить наибольшее значение. Если хотя бы один из аргументов — NaN, результат — неопределенное значение. См.
std.algorithm.searching.maxElementдля примеров работы с NaN.
- См. также:
std.algorithm.searching.maxElement
- Примеры:
-
int a = 5; short b = 6; double c = 2; auto d = max(a, b); assert(is(typeof(d) == int)); writeln(d); // 6 auto e = min(a, b, c); assert(is(typeof(e) == double)); writeln(e); // 2
- auto min(T...)(T args)
Constraints: if (T.length >= 2 && !is(CommonType!T == void)); -
Проходит по переданным аргументам и возвращает минимальное значение.
- Параметры:
T argsЗначения, для которых нужно выбрать минимальное. Должно быть передано как минимум два аргумента, и они должны быть сравнимы с <.
- Возвращает:
- Минимальное из переданных значений. Тип возвращаемого значения — тип среди переданных аргументов, способный хранить наименьшее значение. Если хотя бы один из аргументов — NaN, результат — неопределенное значение. См.
std.algorithm.searching.minElementдля примеров работы с NaN.
- См. также:
std.algorithm.searching.minElement
- Примеры:
-
int a = 5; short b = 6; double c = 2; auto d = min(a, b); static assert(is(typeof(d) == int)); writeln(d); // 5 auto e = min(a, b, c); static assert(is(typeof(e) == double)); writeln(e); // 2 ulong f = 0xffff_ffff_ffff; const uint g = min(f, 0xffff_0000); writeln(g); // 0xffff_0000 dchar h = 100; uint i = 101; static assert(is(typeof(min(h, i)) == dchar)); static assert(is(typeof(min(i, h)) == uint)); writeln(min(h, i)); // 100
- Примеры:
- При аргументах смешанной знаковости, тип возвращаемого значения — тот, что способен хранить наименьшие значения.
int a = -10; uint f = 10; static assert(is(typeof(min(a, f)) == int)); writeln(min(a, f)); // -10
- Примеры:
- Поддерживаются пользовательские типы, поддерживающие сравнение с <.
import std.datetime; writeln(min(Date(2012, 12, 21), Date(1982, 1, 4))); // Date(1982, 1, 4) writeln(min(Date(1982, 1, 4), Date(2012, 12, 21))); // Date(1982, 1, 4) writeln(min(Date(1982, 1, 4), Date.min)); // Date.min writeln(min(Date.min, Date(1982, 1, 4))); // Date.min writeln(min(Date(1982, 1, 4), Date.max)); // Date(1982, 1, 4) writeln(min(Date.max, Date(1982, 1, 4))); // Date(1982, 1, 4) writeln(min(Date.min, Date.max)); // Date.min writeln(min(Date.max, Date.min)); // Date.min
- Tuple!(Range1, Range2) mismatch(alias pred = "a == b", Range1, Range2)(Range1 r1, Range2 r2)
Constraints: if (isInputRange!Range1 && isInputRange!Range2); -
Последовательно сравнивает элементы в
r1иr2пошагово и останавливается на первой несовпадении (согласноpred, по умолчанию равенству). Возвращает кортеж с уменьшенными диапазонами, начинающимися с двух несовпадающих значений. Выполняет Ο(min(r1.length, r2.length)) вычисленийpred.- Примеры:
-
int[6] x = [ 1, 5, 2, 7, 4, 3 ]; double[6] y = [ 1.0, 5, 2, 7.3, 4, 8 ]; auto m = mismatch(x[], y[]); writeln(m[0]); // x[3 .. $] writeln(m[1]); // y[3 .. $]
- auto predSwitch(alias pred = "a == b", T, R...)(T switchExpression, lazy R choices);
-
Возвращает одно из набора выражений на основе значения выражения переключения.
choicesдолжен состоять из пар выражений проверки и выражений возврата. Каждое выражение проверки сравнивается сswitchExpressionс использованиемpred(switchExpression— первый аргумент), и если это даёт true — возвращается выражение возврата.
И выражения проверки, и выражения возврата вычисляются лениво.- Параметры:
T switchExpressionПервый аргумент для предиката. R choicesПары выражений проверки и выражений возврата. Выражения проверки будут вторым аргументом для предиката, и выражение возврата будет возвращено, если предикат даёт true с switchExpressionи выражением проверки в качестве аргументов. Может также иметь выражение возврата по умолчанию, которое должно быть последним выражением без выражения проверки перед ним. Выражение возврата может быть только типа void, если оно всегда вызывает исключение.
- Возвращает:
- Выражение возврата, связанное с первым выражением проверки, которое заставило предикат вернуть true, или выражение возврата по умолчанию, если ни одно выражение проверки не совпало.
- Исключения:
- Если нет выражения возврата по умолчанию и предикат не возвращает true ни с одним выражением проверки — выбрасывается
SwitchError.SwitchErrorтакже будет вызвано, если выражение возврата типа void было выполнено без возбуждения исключения.
- Примеры:
-
string res = 2.predSwitch!"a < b"( 1, "less than 1", 5, "less than 5", 10, "less than 10", "greater or equal to 10"); writeln(res); // "less than 5" //The arguments are lazy, which allows us to use predSwitch to create //recursive functions: int factorial(int n) { return n.predSwitch!"a <= b"( -1, {throw new Exception("Can not calculate n! for n < 0");}(), 0, 1, // 0! = 1 n * factorial(n - 1) // n! = n * (n - 1)! for n >= 0 ); } writeln(factorial(3)); // 6 //Void return expressions are allowed if they always throw: import std.exception : assertThrown; assertThrown!Exception(factorial(-9));
- bool isSameLength(Range1, Range2)(Range1 r1, Range2 r2)
Constraints: if (isInputRange!Range1 && isInputRange!Range2); -
Проверяет, имеют ли два диапазона одинаковое количество элементов. Эта функция оптимизирована для использования члена
lengthлюбого диапазона, если он существует.Если у обоих диапазонов есть член length, эта функция имеет сложность Ο(
1). В противном случае сложность Ο(min(r1.length, r2.length)).
Бесконечные диапазоны считаются имеющими одинаковую длину. Бесконечный диапазон никогда не имеет одинаковую длину с конечным диапазоном.- Параметры:
Range1 r1конечный входной диапазон Range2 r2конечный входной диапазон
- Возвращает:
-
trueесли оба диапазона имеют одинаковую длину,falseв противном случае.
- Примеры:
-
assert(isSameLength([1, 2, 3], [4, 5, 6])); assert(isSameLength([0.3, 90.4, 23.7, 119.2], [42.6, 23.6, 95.5, 6.3])); assert(isSameLength("abc", "xyz")); int[] a; int[] b; assert(isSameLength(a, b)); assert(!isSameLength([1, 2, 3], [4, 5])); assert(!isSameLength([0.3, 90.4, 23.7], [42.6, 23.6, 95.5, 6.3])); assert(!isSameLength("abcd", "xyz"));
- bool isPermutation(Flag!"allocateGC" allocateGC, Range1, Range2)(Range1 r1, Range2 r2)
Constraints: if (allocateGC == Yes.allocateGC && isForwardRange!Range1 && isForwardRange!Range2 && !isInfinite!Range1 && !isInfinite!Range2);
bool isPermutation(alias pred = "a == b", Range1, Range2)(Range1 r1, Range2 r2)
Constraints: if (is(typeof(binaryFun!pred)) && isForwardRange!Range1 && isForwardRange!Range2 && !isInfinite!Range1 && !isInfinite!Range2); -
Проверяет, являются ли оба диапазона перестановкой друг друга.
Эта функция может выделять память, если флаг
Yes.allocateGCпередан. Это даёт преимущество в сложности по сравнению с вариантомYes.allocateGC. Однако этот вариант доступен только для диапазонов, равенство которых может быть определено с помощью методаtoHashкаждого элемента. Если требуется настраиваемое равенство, то может быть передан шаблонный параметрpred, и функция автоматически переключится на невыделяющий алгоритм. См.std.functional.binaryFunдля получения более подробной информации о том, как определитьpred.
Вариант невыделяющего диапазона с forward: Ο(n^2) Вариант невыделяющего диапазона с forward и настраиваемымpred: Ο(n^2) Вариант выделяющего диапазона с forward: амортизированное Ο(r1.length) + Ο(r2.length)- Параметры:
pred необязательный параметр для изменения определения равенства allocateGC Yes.allocateGC/No.allocateGCRange1 r1Конечный forward диапазон Range2 r2Конечный forward диапазон
- Возвращает:
-
trueесли все элементы вr1появляются одинаковое количество раз вr2. В противном случае возвращаетfalse.
- Примеры:
-
import std.typecons : Yes; assert(isPermutation([1, 2, 3], [3, 2, 1])); assert(isPermutation([1.1, 2.3, 3.5], [2.3, 3.5, 1.1])); assert(isPermutation("abc", "bca")); assert(!isPermutation([1, 2], [3, 4])); assert(!isPermutation([1, 1, 2, 3], [1, 2, 2, 3])); assert(!isPermutation([1, 1], [1, 1, 1])); // Faster, but allocates GC handled memory assert(isPermutation!(Yes.allocateGC)([1.1, 2.3, 3.5], [2.3, 3.5, 1.1])); assert(!isPermutation!(Yes.allocateGC)([1, 2], [3, 4]));
- CommonType!(T, Ts) either(alias pred = (a) => a, T, Ts...)(T first, lazy Ts alternatives)
Constraints: if (alternatives.length >= 1 && !is(CommonType!(T, Ts) == void) && allSatisfy!(ifTestable, T, Ts));
-
Получить первый аргумент
a, который проходитif (unaryFun!pred(a))тест. Если ни один аргумент не проходит тест, вернуть последний аргумент.Аналогично поведению оператора
orв динамических языках, таких как Lisp's(or ...)и Python'sa or b or ..., за исключением того, что при отсутствии совпадения возвращается последний аргумент.
Упрощает логику, например, в правилах разбора, где пытаются сопоставить набор альтернативных проверяющих средств. Первый, который совпадёт, возвращает результат его сопоставления, как правило, в виде абстрактного синтаксического дерева (AST).- Ошибки:
- Ленивые параметры в настоящее время слишком ограничительно выводятся DMD как всегда выбрасывающие исключение, даже если это не требуется. Это делает невозможным в настоящее время пометить
eitherкакnothrow. См. вопрос в Bugzilla 12647.
- Возвращаемое значение:
- Первый аргумент, который проходит тест
pred.
- Примеры:
-
const a = 1; const b = 2; auto ab = either(a, b); static assert(is(typeof(ab) == const(int))); writeln(ab); // a auto c = 2; const d = 3; auto cd = either!(a => a == 3)(c, d); // use predicate static assert(is(typeof(cd) == int)); writeln(cd); // d auto e = 0; const f = 2; auto ef = either(e, f); static assert(is(typeof(ef) == int)); writeln(ef); // f
- Примеры:
-
immutable p = 1; immutable q = 2; auto pq = either(p, q); static assert(is(typeof(pq) == immutable(int))); writeln(pq); // p writeln(either(3, 4)); // 3 writeln(either(0, 4)); // 4 writeln(either(0, 0)); // 0 writeln(either("", "a")); // ""
- Примеры:
-
string r = null; writeln(either(r, "a")); // "a" writeln(either("a", "")); // "a" immutable s = [1, 2]; writeln(either(s, s)); // s writeln(either([0, 1], [1, 2])); // [0, 1] writeln(either([0, 1], [1])); // [0, 1] writeln(either("a", "b")); // "a" static assert(!__traits(compiles, either(1, "a"))); static assert(!__traits(compiles, either(1.0, "a"))); static assert(!__traits(compiles, either('a', "a")));
© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_algorithm_comparison.html