Я не понял, откуда индекс у элемента последовательности? Индекс есть у элемента массива, а у элемента последовательности понятия первого элемента, последнего, текущего и возможность перейти к следующему. ))
А это LINQ из .Net Select / Where поддерживают выдачу элемента, а также элемента и его индекса.
Не индекса. Порядкового номера в процессе перебора, отсчитываемого от нуля. Дело в том, что для PascalАВС.NЕТ и массив, и список List, и кое-что еще - разновидности все той же последовательности. Поэтому в Where, Select и т.п. LINQ старается экземпляр входного контейнерного класса “разобрать” в стандартную последовательность.
Да. Именно номер элемента в последовательности, начиная с 0
А чего я то сразу?))
Она есть при объявлении локальных переменные (но не параметров) и в is-var
.
begin
ReadArrInteger(ReadInteger)
.Combinations(2)
.Select(x->(x[0],x[1])) // ниже строчка не работает
.Where(x->
begin
if x is (var a,var b) then
Result := ((a+b)mod 80 =0)and((a>50)or(b>50));
end)
.Print();
end.
Вообще должно быть возможно красивее:
begin
ReadArrInteger(ReadInteger)
.Combinations(2)
.Select(x->(x[0],x[1]))
.Where(x->(x is (var a,var b)) and ((a+b)mod 80 =0)and((a>50)or(b>50)))
.Print();
end.
Where((x,y)->…) - тут надо не забывать, что x,y не могут трактоваться здесь как кортежи - это параметры лямбды. И ещё я не понял - зачем массив из двух элементов превращать в кортеж - всё равно потом обращаемся по индексам t[0] и t[1]
Да, там есть деконструктор на две переменные - не обратил внимания. Но в вашем контексте он не развернётся - так что сообщение правильное. В некоторых контекстах где нет явной секции операторов эта конструкция запрещена
А, кстати да, is-var
тоже может работает с массивами:
begin
ReadArrInteger(ReadInteger)
.Combinations(2)
.Where(x->
begin
if x is [var a,var b] then
Result := ((a+b)mod 80 =0)and((a>50)or(b>50)) else
raise new System.InvalidOperationException;
end)
.Print();
end.
Тут, получается, проверяет не только x<>nil
, но ещё и x.Length=2
. Что очень хорошо, если решите заменить ReadArrInteger.Combinations
на что то другое - тело Where
не надо менять.
Я же сказал - в этом контексте не поддерживается. И не будет.
То есть с указанием типа будет работать:
begin
var t: (integer, integer);
var res := t is System.Tuple<integer,integer>(var a, var b);
end.
А с сахаром - нет? Неужели так сложно?
Не понял. Что сложно?
Всё ради краткости кода. Иначе на каждую переменную еще по три символа [0]/[1], что усложняет чтение кода. Мне эта идея кажется полезной.
Да, я тоже не понял что сложно, потому что это:
t is System.Tuple<integer,integer>(var a, var b)
И это:
t is (var a, var b)
Один и тот же код, но второй - с дополнительным слоем сахара. То есть, скорее всего, всё “не поддерживается” заключается в чём то типа нехватки дубля метода визитора.
Я смотрю все коммиты-фиксы issue и обычно такое исправлялось 1-2 строчками.
Честно говоря, это экспериментальный код - он не должен быть в основном языке. Я не знаю, откуда вы его взяли.
t is System.Tuple<integer,integer>
- это обычный is
t is System.Tuple<integer,integer>(var a, var b)
- это расширенный is - с деконструктором
Эти элементы в языке есть
В последнем примере так писать немного глупо - обычно t должно иметь тип надкласса
а почему бы не так?
t is var (a,b)
это уже похоже на pattern matching и тут я пока слаб в хороших идеях. Моя интерпретация: проверяем что это кортеж из двух элементов и помещаем значения элементов кортежа в локальные переменные a и b
Паттерн матчинг берет своё начало из расширенного is. Расширенный is это -
перем is СовместимыйТип(var перемДляДеконтрукции)
Об этом случае представление у меня более менее есть. На C# регулярно использую. Хуже понимание реализаций в F#. Еще есть плохое различение паттерн матчинга с унификацией в Прологе. Много общего, но есть и различия
В смысле эксперементальный? Это же было добавлено вместе с a is [...]
и т.п., в обновлении паттерн-мачинга, о котором вы на странице изменений писали. Или нет?
Вот, отсюда:
[25.05.19] Версия 3.5.0.2067
- Улучшения Pattern Matching - Pattern Matching с IList, кортежами, константами
Про кортежи явно сказано, прямо рядом с IList
.
Вот для IList
это is [...]
, а для кортежей - is (...)
.