Есть последовательность чисел {1, 3, 5, 7, 9}
Надо проверить что числа следуют по возрастанию
Можно сделать при помощи linq?
Re: [Linq] проверить последовательность
От:
Аноним
Дата:
30.07.10 16:55
Оценка:
Здравствуйте, Dog, Вы писали:
Dog>Есть последовательность чисел {1, 3, 5, 7, 9} Dog>Надо проверить что числа следуют по возрастанию Dog>Можно сделать при помощи linq?
var s = new[] {1, 3, 3, 7, 9};
var r = s.Aggregate(new {V=int.MinValue, C=0}, (a, val) => a.V < val ? new {V=val, C=a.C+1} : a).C == s.Length;
Здравствуйте, Dog, Вы писали:
Dog>Есть последовательность чисел {1, 3, 5, 7, 9} Dog>Надо проверить что числа следуют по возрастанию Dog>Можно сделать при помощи linq?
c Rx можно?
public static IEnumerable<int> Enumerate()
{
...
}
public static void Main(string[] args)
{
var ascending = Enumerate()
.Memoize(1)
.Let(e => e.Zip(e.Skip(1), (a, b) => a < b))
.All(x => x);
}
Здравствуйте, Dog, Вы писали:
Dog>Есть последовательность чисел {1, 3, 5, 7, 9} Dog>Надо проверить что числа следуют по возрастанию Dog>Можно сделать при помощи linq?
Неэффективно, но декларативненько:
var isAscending = xs.OrderBy(x => x).SequenceEqual(xs);
На Rx мона чуть короче:
var isAscending = xs.Replay(ys => ys.Zip(ys.Skip(1), (x, y) => x <= y), 1).All(x => x);
Здравствуйте, Dog, Вы писали:
Dog>Есть последовательность чисел {1, 3, 5, 7, 9} Dog>Надо проверить что числа следуют по возрастанию Dog>Можно сделать при помощи linq?
static void Main(string[] args)
{
var a = new[] { 1, 2, 3, 4, 5 };
int last = 0;
var asc = a.Select(x => { if (x >= last) { last = x; return true; } else return false; }).All(x=>x);
Console.WriteLine(asc);
}
Прошу прощения. А не проще ли и не понятее ли написать простенкий цикл с временной переменной? Или, профессиональный программист обязательно должен втулить это уродство куда ни попади, дабы все знали что он слышал про Linq и умеет им пользоваться?
П>На Rx мона чуть короче: П>
0K>Прошу прощения. А не проще ли и не понятее ли написать простенкий цикл с временной переменной? Или, профессиональный программист обязательно должен втулить это уродство куда ни попади, дабы все знали что он слышал про Linq и умеет им пользоваться?
П>>На Rx мона чуть короче: П>>
0K>Что такое Rx? Это какая-то библиотека, или подход к написанию этих ваших Linq?
0K>Вам это правда понятее простого цикла с одной единственной временной переменной?
походу вопрос с собеседования или с экзамена, Rx действительно нах нужно
0K>Прошу прощения. А не проще ли и не понятее ли написать простенкий цикл с временной переменной? Или, профессиональный программист обязательно должен втулить это уродство куда ни попади, дабы все знали что он слышал про Linq и умеет им пользоваться?
Я далеко не "профессиональный программист", но попытаюсь Вам ответить. Дело в том, что если прочитать первый пост данной темы, то можно понять, что топикстартер хотел получить решение на базе Linq и я думаю Вас не должны сильно волновать причины потребности именно Linq-решения. Если Вас раздражает наличие в языке и BCL подобных штук, то думаю это с удовольствием обсудят на холиварных форумах.
Насчёт "уродства" — императивные циклы с мутабельными переменными и break-переходом куда красивше, дааа
П>>На Rx мона чуть короче: П>>
0K>Что такое Rx? Это какая-то библиотека, или подход к написанию этих ваших Linq?
Ну а почему бы не погуглить?
Это библиотека для работы с реактивными последовательностями (a.k.a. observer pattern), а так же некоторые дополнительные комбинаторы для работы с обычными интерактивными IEnumerable-последовательностями, которых иногда очень не хватает. Очень советую посмотреть, много интересного там
0K>Вам это правда понятее простого цикла с одной единственной временной переменной?
Это просто другой подход для решения поставленной задачи, декларативный. Не нужны никакие циклы и переменные, надо лишь собрать нужный Вам алгоритм из комбинируемых кусочков, представленных в Rx. Да, это не очень понятно выглядит на первый взгляд, но это можно даже прочитать:
Помня одно предыдущее значение, соедини последовательность с самой собой, смещённой с на один элемент вперёд, и проверь, что во всех парах левое значение меньше или равно правому.
Это просто другой "мирок", никто Вам не навязывает подобные техники и подходы. Ну не нравится — ну не пользуйтесь, проблем то
в вашем случае исходная последовательность будет перебираться дважды
var sequence = new[] { 1, 2, 3, 4, 5, 6 }.Do(Console.Write);
var isAscending = sequence
.Zip(sequence.Skip(1), (x, y) => x <= y)
.All(x => x); // 112233445566
для того, чтобы этого избежать нужно запоминать последний элемент (Memoize(1))
var sequence = new[] { 1, 2, 3, 4, 5, 6 }.Do(Console.Write).Memoize(1);
var isAscending = sequence
.Zip(sequence.Skip(1), (x, y) => x <= y)
.All(x => x); //123456
IB>А вот с Rx можно попробовать сделать так, чтобы перебор останавливался как только случится первое неудовлетворение предикату...
а это обеспечивает стандартный All
var sequence = new[] { 1, 2, 3, 2, 4, 5, 6 }.Do(Console.Write).Memoize(1);
var isAscending = sequence
.Zip(sequence.Skip(1), (x, y) => x <= y)
.All(x => x); //1232
Здравствуйте, desco, Вы писали:
D>в вашем случае исходная последовательность будет перебираться дважды
Не совсем так, не перебираться дважды, а дважды обращаться к одному и тому же элементу. =)
D>для того, чтобы этого избежать нужно запоминать последний элемент (Memoize(1))
Да, эта функция уже в Rx...
D>а это обеспечивает стандартный All
Верно =)
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, desco, Вы писали:
D>>в вашем случае исходная последовательность будет перебираться дважды IB>Не совсем так, не перебираться дважды, а дважды обращаться к одному и тому же элементу. =)
перебирается-перебирается
class Seq : IEnumerable<int>
{
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<int> GetEnumerator()
{
Console.WriteLine("GetEnumerator");
Console.WriteLine(1);
yield return 1;
Console.WriteLine(2);
yield return 2;
Console.WriteLine(3);
yield return 3;
}
}
class Program
{
static void Main(string[] args)
{
var sequence = new Seq();
// var sequence = new Seq().Memoize(1);var isAscending = sequence
.Zip(sequence.Skip(1), (x, y) => x <= y)
.All(x => x);
}
}
Здравствуйте, desco, Вы писали:
D>перебирается-перебирается
Мммм.. Сформулируем еще точнее — создаются два итератора, которые поочереди обращаются к одному и тому же элементу. =)
Подозреваю, что накладные расходы на Memoize() и дополнительный итератор в среднем одинаковы, при стандартных сценариях. Вот если бы нам пришла блажь за каждым элементом лезть, например, в базу...
Здравствуйте, Dog, Вы писали:
Dog>Есть последовательность чисел {1, 3, 5, 7, 9} Dog>Надо проверить что числа следуют по возрастанию Dog>Можно сделать при помощи linq?
Скажи пожалуйста, с какой целью ты задал вопрос ?
Вроде ж до сих пор ты не был студентом, а вопрос задал студенческий
У меня есть одно предположение, какое то решение у тебя есть и тебе нужны были варианты. Но для чего это надо — не ясно. Собеседование проводишь или сам ходишь по оным ?
П>Это просто другой "мирок", никто Вам не навязывает подобные техники и подходы. Ну не нравится — ну не пользуйтесь, проблем то
Это другой мирок. Это другой, новый, прекрасный мирок. В нем живут более разумные, более совершенные, "другие" люди.
Не пытайтесь их понять, возможно, вам этого просто не дано. Они "другие". Они просто "другие".
Я уже послал Андерсу Хейлсбергу письмо c предложением включить в C# два кейворда для разделения императивного и декларативного кода:
// Кейворд aliens помечает декларативный код для "других" людей.
aliens
{
var isAscending = xs.Replay(ys => ys.Zip(ys.Skip(1), (x, y) => x <= y), 1).All(x => x);
}
// Кейворд bydlokod помечает императивный код.
bydlokod
{
bool isAscending = true;
for (int i = 1; i < numbers.Length; i++)
{
if (numbers[i - 1] > numbers[i])
{
isAscending = false;
break;
}
}
}
Так сразу будет видно, чей код где.
Правда, какой режим будет по умолчанию, я еще не придумал, наверно, все-таки bydlokod. Варваров всегда большинство, и они темной массой окружают цивилизованное государство, угрожая его истребить.
Собрался ставить минус? Да сам иди в жопу!
.
Re[5]: [Linq] проверить последовательность
От:
Аноним
Дата:
31.07.10 23:24
Оценка:
Здравствуйте, SpaceConscience, Вы писали:
SC>Я уже послал Андерсу Хейлсбергу письмо c предложением включить в C# два кейворда для разделения императивного и декларативного кода:
SC>