[Linq] проверить последовательность
От: Dog  
Дата: 30.07.10 15:11
Оценка:
Есть последовательность чисел {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;
Re: [Linq] проверить последовательность
От: desco США http://v2matveev.blogspot.com
Дата: 30.07.10 18:48
Оценка: 18 (3)
Здравствуйте, 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);
        }
Re: [Linq] проверить последовательность
От: Пельмешко Россия blog
Дата: 30.07.10 23:44
Оценка: -1 :))
Здравствуйте, 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);


Re: [Linq] проверить последовательность
От: kkolyan  
Дата: 31.07.10 08:16
Оценка: :)
Здравствуйте, 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);
            

        }
Re[2]: [Linq] проверить последовательность
От: 0K Ниоткуда  
Дата: 31.07.10 10:07
Оценка: +1 -3
Здравствуйте, Пельмешко, Вы писали:

П>Неэффективно, но декларативненько:

П>
П>var isAscending = xs.OrderBy(x => x).SequenceEqual(xs);
П>


Прошу прощения. А не проще ли и не понятее ли написать простенкий цикл с временной переменной? Или, профессиональный программист обязательно должен втулить это уродство куда ни попади, дабы все знали что он слышал про Linq и умеет им пользоваться?

П>На Rx мона чуть короче:

П>
П>var isAscending = xs.Replay(ys => ys.Zip(ys.Skip(1), (x, y) => x <= y), 1).All(x => x);
П>


Что такое Rx? Это какая-то библиотека, или подход к написанию этих ваших Linq?

Вам это правда понятее простого цикла с одной единственной временной переменной?
Re[3]: [Linq] проверить последовательность
От: kkolyan  
Дата: 31.07.10 10:30
Оценка:
Здравствуйте, 0K, Вы писали:

0K>Здравствуйте, Пельмешко, Вы писали:


П>>Неэффективно, но декларативненько:

П>>
П>>var isAscending = xs.OrderBy(x => x).SequenceEqual(xs);
П>>


0K>Прошу прощения. А не проще ли и не понятее ли написать простенкий цикл с временной переменной? Или, профессиональный программист обязательно должен втулить это уродство куда ни попади, дабы все знали что он слышал про Linq и умеет им пользоваться?


П>>На Rx мона чуть короче:

П>>
П>>var isAscending = xs.Replay(ys => ys.Zip(ys.Skip(1), (x, y) => x <= y), 1).All(x => x);
П>>


0K>Что такое Rx? Это какая-то библиотека, или подход к написанию этих ваших Linq?


0K>Вам это правда понятее простого цикла с одной единственной временной переменной?


походу вопрос с собеседования или с экзамена, Rx действительно нах нужно
Re[3]: [Linq] Всех несогласных просьба сюда
От: 0K Ниоткуда  
Дата: 31.07.10 11:02
Оценка:
Здравствуйте, 0K, Вы писали:

Кто может обосновать что я не прав: http://rsdn.ru/forum/flame.comp/3900658.flat.aspx
Автор: 0K
Дата: 31.07.10
Re[4]: [Linq] проверить последовательность
От: 0K Ниоткуда  
Дата: 31.07.10 11:03
Оценка:
Здравствуйте, kkolyan, Вы писали:

K>походу вопрос с собеседования или с экзамена, Rx действительно нах нужно


Что какое Rx?
Re[3]: [Linq] проверить последовательность
От: Пельмешко Россия blog
Дата: 31.07.10 11:10
Оценка: 8 (3) :)
Здравствуйте, 0K, Вы писали:

0K>Здравствуйте, Пельмешко, Вы писали:


П>>Неэффективно, но декларативненько:

П>>
П>>var isAscending = xs.OrderBy(x => x).SequenceEqual(xs);
П>>


0K>Прошу прощения. А не проще ли и не понятее ли написать простенкий цикл с временной переменной? Или, профессиональный программист обязательно должен втулить это уродство куда ни попади, дабы все знали что он слышал про Linq и умеет им пользоваться?


Я далеко не "профессиональный программист", но попытаюсь Вам ответить. Дело в том, что если прочитать первый пост данной темы, то можно понять, что топикстартер хотел получить решение на базе Linq и я думаю Вас не должны сильно волновать причины потребности именно Linq-решения. Если Вас раздражает наличие в языке и BCL подобных штук, то думаю это с удовольствием обсудят на холиварных форумах.

Насчёт "уродства" — императивные циклы с мутабельными переменными и break-переходом куда красивше, дааа

П>>На Rx мона чуть короче:

П>>
П>>var isAscending = xs.Replay(ys => ys.Zip(ys.Skip(1), (x, y) => x <= y), 1).All(x => x);
П>>


0K>Что такое Rx? Это какая-то библиотека, или подход к написанию этих ваших Linq?


Ну а почему бы не погуглить?
Это библиотека для работы с реактивными последовательностями (a.k.a. observer pattern), а так же некоторые дополнительные комбинаторы для работы с обычными интерактивными IEnumerable-последовательностями, которых иногда очень не хватает. Очень советую посмотреть, много интересного там

0K>Вам это правда понятее простого цикла с одной единственной временной переменной?


Это просто другой подход для решения поставленной задачи, декларативный. Не нужны никакие циклы и переменные, надо лишь собрать нужный Вам алгоритм из комбинируемых кусочков, представленных в Rx. Да, это не очень понятно выглядит на первый взгляд, но это можно даже прочитать:

Помня одно предыдущее значение, соедини последовательность с самой собой, смещённой с на один элемент вперёд, и проверь, что во всех парах левое значение меньше или равно правому.


Это просто другой "мирок", никто Вам не навязывает подобные техники и подходы. Ну не нравится — ну не пользуйтесь, проблем то
Re[2]: [Linq] проверить последовательность
От: IB Австрия http://rsdn.ru
Дата: 31.07.10 11:31
Оценка:
Здравствуйте, Пельмешко, Вы писали:

П>
П>var isAscending = xs.Replay(ys => ys.Zip(ys.Skip(1), (x, y) => x <= y), 1).All(x => x);
П>


Можно проще и без Rx. =) К счастью в 4FW метод Zip — часть LINQ.

var isAscending = sequence.Zip(sequence.Skip(1), (x, y) => x <= y).All(x => x);


А вот с Rx можно попробовать сделать так, чтобы перебор останавливался как только случится первое неудовлетворение предикату...
Мы уже победили, просто это еще не так заметно...
Re[2]: [Linq] проверить последовательность
От: Jolly Roger  
Дата: 31.07.10 11:42
Оценка: 1 (1) +1 :)
Здравствуйте, Пельмешко, Вы писали:

П>
П>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);
П>


У Вас оператор "короче" перегружен?

П>

"Нормальные герои всегда идут в обход!"
Re[3]: [Linq] проверить последовательность
От: desco США http://v2matveev.blogspot.com
Дата: 31.07.10 12:50
Оценка: 2 (1) +2
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Пельмешко, Вы писали:


П>>
П>>var isAscending = xs.Replay(ys => ys.Zip(ys.Skip(1), (x, y) => x <= y), 1).All(x => x);
П>>


IB>Можно проще и без Rx. =) К счастью в 4FW метод Zip — часть LINQ.


IB>
IB>var isAscending = sequence.Zip(sequence.Skip(1), (x, y) => x <= y).All(x => x);
IB>



в вашем случае исходная последовательность будет перебираться дважды

            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
Re[4]: [Linq] проверить последовательность
От: IB Австрия http://rsdn.ru
Дата: 31.07.10 13:43
Оценка:
Здравствуйте, desco, Вы писали:

D>в вашем случае исходная последовательность будет перебираться дважды

Не совсем так, не перебираться дважды, а дважды обращаться к одному и тому же элементу. =)

D>для того, чтобы этого избежать нужно запоминать последний элемент (Memoize(1))

Да, эта функция уже в Rx...

D>а это обеспечивает стандартный All

Верно =)
Мы уже победили, просто это еще не так заметно...
Re[5]: [Linq] проверить последовательность
От: desco США http://v2matveev.blogspot.com
Дата: 31.07.10 14:06
Оценка:
Здравствуйте, 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); 
        }
    }


GetEnumerator
1
GetEnumerator
1
2
2
3

3


вариант с Memoize

GetEnumerator
1
2
3

Re[6]: [Linq] проверить последовательность
От: IB Австрия http://rsdn.ru
Дата: 31.07.10 14:21
Оценка:
Здравствуйте, desco, Вы писали:

D>перебирается-перебирается

Мммм.. Сформулируем еще точнее — создаются два итератора, которые поочереди обращаются к одному и тому же элементу. =)
Подозреваю, что накладные расходы на Memoize() и дополнительный итератор в среднем одинаковы, при стандартных сценариях. Вот если бы нам пришла блажь за каждым элементом лезть, например, в базу...
Мы уже победили, просто это еще не так заметно...
Re[4]: [Linq] проверить последовательность
От: FR  
Дата: 31.07.10 17:25
Оценка:
Здравствуйте, Пельмешко, Вы писали:

П>Насчёт "уродства" — императивные циклы с мутабельными переменными и break-переходом куда красивше, дааа


Я конечно лезу не в свое болото но похоже эта задача не для Linq.
Что не мешает ее написать функционально http://www.rsdn.ru/forum/flame.comp/3900693.1.aspx
Автор: FR
Дата: 31.07.10

Или даже на вполне императивном D

auto f(int Arr[])
{
    if(Arr.length < 2)
        return true;
    
    if(Arr[0] > Arr[1])
        return false;
    
    return f(Arr[0 .. $ - 1]);
}


но в функциональном стиле, с хвостовой рекурсией и эффективностью близкой к циклу.
На Шарпе или C++ будет почти также.
Re: [Linq] проверить последовательность
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 31.07.10 19:00
Оценка:
Здравствуйте, Dog, Вы писали:

Dog>Есть последовательность чисел {1, 3, 5, 7, 9}

Dog>Надо проверить что числа следуют по возрастанию
Dog>Можно сделать при помощи linq?

Скажи пожалуйста, с какой целью ты задал вопрос ?
Вроде ж до сих пор ты не был студентом, а вопрос задал студенческий
У меня есть одно предположение, какое то решение у тебя есть и тебе нужны были варианты. Но для чего это надо — не ясно. Собеседование проводишь или сам ходишь по оным ?
Re[4]: [Linq] проверить последовательность
От: SpaceConscience  
Дата: 31.07.10 20:28
Оценка: +2 -1 :))
П>Это просто другой "мирок", никто Вам не навязывает подобные техники и подходы. Ну не нравится — ну не пользуйтесь, проблем то

Это другой мирок. Это другой, новый, прекрасный мирок. В нем живут более разумные, более совершенные, "другие" люди.

Не пытайтесь их понять, возможно, вам этого просто не дано. Они "другие". Они просто "другие".

Я уже послал Андерсу Хейлсбергу письмо 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>
SC>// Кейворд bydlokod помечает императивный код.
SC>bydlokod
SC>{
SC>    bool isAscending = true;
SC>    for (int i = 1; i < numbers.Length; i++)
SC>    {
SC>        if (numbers[i - 1] > numbers[i])
SC>        {
SC>            isAscending = false;
SC>            break;
SC>        }
SC>    }
SC>}
SC>


Ну киворд — это полумера...
let isAscending xs = xs |> Seq.pairwise |> Seq.forall (fun (a,b) -> a <= b)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.