Есть более простой способ использовать оператор метода groupBy приема?


Я просто играю с концепцией метода groupBy внутри ГХ. Так вот, я подумал, как трудно было бы написать консольное приложение, которое постоянно читает строки, группирует их на похожие слова и просто выводит слово среди нынешнего графа, как часто это слово было написано раньше. Это действительно был легкий ветерок, чтобы сделать это, но я интересно, если моя попытка может быть переписан в более элегантный способ. Особенно если я смогу избавиться от вложенных поддерживает.

Вот что у меня:

static void Main(string[] args)
{
    var subject = new Subject<string>();

    var my = subject.GroupBy(x => x);

    my.Subscribe(x => x.Scan(new { Chars = string.Empty, Count = 0},
                                 (a, chars) => new { Chars = chars, Count = a.Count + 1})
      .Subscribe(result => Console.WriteLine("You typed {0} {1} times", result.Chars, 
                 result.Count)));

    while (true)
    {
        subject.OnNext(Console.ReadLine());
    }
}

Результат

test
you typed test 1 times
test
you typed test 2 times
hallo
you typed test 1 times
test
you typed test 3 times
...


2716
6
задан 12 ноября 2011 в 05:11 Источник Поделиться
Комментарии
3 ответа

Ок, это выглядит намного лучше! Может кто-нибудь даже сделать лучше, чем что?

    static void Main(string[] args)
{
var subject = new Subject<string>();

subject
.GroupBy(x => x)
.SelectMany(x => x.Scan(new { Chars = string.Empty, Count = 0},(a, chars) => new { Chars = chars, Count = a.Count + 1}))
.Subscribe(result => Console.WriteLine("You typed {0} {1} times", result.Chars, result.Count));

while (true)
{
subject.OnNext(Console.ReadLine());
}
}

1
ответ дан 12 ноября 2011 в 05:11 Источник Поделиться

ОК, Вот еще один! Я думаю, что это легче читать, поскольку мы не зависим от метода сканирования переносить строку с помощью вычисления:

    static void Main(string[] args)
{
var subject = new Subject<string>();

subject
.GroupBy(x => x)
.SelectMany(x => x.Scan(0, (count, _) => ++count).Zip(x, (count, chars) => new { Chars = chars, Count = count}))
.Subscribe(result => Console.WriteLine("You typed {0} {1} times", result.Chars, result.Count));

while (true)
{
subject.OnNext(Console.ReadLine());
}
}

Может кто-нибудь сделать еще лучше?

1
ответ дан 12 ноября 2011 в 06:11 Источник Поделиться

Это выглядит намного чище меня. Следует также продемонстрировать, насколько более это полезно, когда вы дать более описательные имена переменных.

static void Main(string[] args)
{
var lineReader = new Subject<string>();

lineReader.GroupBy(line => line)
.Subscribe(lineGroup =>
{
lineGroup.Scan(0, (acc, _) => ++acc)
.Subscribe(count =>
{
var line = lineGroup.Key;
var timeSuffix = count == 1 ? "" : "s";
Console.WriteLine("You typed {0} {1} time{2}.", line, count, timeSuffix);
});
});

String readLine;
while ((readLine = Console.ReadLine()) != null)
lineReader.OnNext(readLine);
}

1
ответ дан 12 марта 2012 в 02:03 Источник Поделиться