Как сделать выбор группы по фиксированному номеру, используя Linq для объектов? - PullRequest
3 голосов
/ 25 января 2012
data.Select(object=> string.Format("<a>{0}</a>", object.LinkText))      
.Select(html => string.Format("<div>{0}</div>", html))    
.Aggregate((running, next) => running + next);

У меня есть этот запрос, который в основном превращает некоторые объекты в html-разметку. Чего я не могу достичь, так это того, что второй выбор должен выполняться только для каждого (фиксированного числа) 3 элементов в первом выборе. Я не хочу, чтобы мой результат был примерно таким:

<div><a>xxx</a><a>yyy</a><a>zzz</a></div>
<div><a>ååå</a>....</div>

Пожалуйста, помогите мне избежать цикла!

Ответы [ 3 ]

3 голосов
/ 25 января 2012

Чтобы сгруппировать по 3, используйте этот запрос LINQ:

    var data = new[] {"quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"};
    var res = data
        .Select((s, i) => new { Link = string.Format("<a>{0}</a>", s), Index = i })
        .GroupBy(p => p.Index/3)
        .Select(g => string.Format("<div>{0}</div>", string.Join("", g.Select(v => v.Link))));
    foreach (var re in res) {
        Console.WriteLine(re);
    }

Вывод этой программы выглядит следующим образом:

<div><a>quick</a><a>brown</a><a>fox</a></div>
<div><a>jumps</a><a>over</a><a>the</a></div>
<div><a>lazy</a><a>dog</a></div>

Обратите внимание, как этот код использует string.Join вместо более медленного Aggregate. Конечно, поскольку вы используете некоторые другие объекты вместо строк, вам нужно заменить string.Format("<a>{0}</a>", s) на string.Format("<a>{0}</a>", s.LinkText).

0 голосов
/ 25 января 2012

Следующее должно дать вам желаемый результат:

 var data = new List<String>();
            data.BreakIntoChunks(3).Select(html => string.Format("<div>{0}</div>", String.Join("", (html.Select(
                item => string.Format("<a>{0}</a>", item))).ToArray())));
        ...

    public static class EnumerableExt
    {
        public static IEnumerable<IEnumerable<TRecord>> BreakIntoChunks<TRecord>(this IEnumerable<TRecord> items,
                                                                                 int chunkSize)
        {
            int itemCount = 0;
            var processedItems = new List<TRecord>();
            foreach (TRecord record in items)
            {
                ++itemCount;
                processedItems.Add(record);
                if (itemCount%chunkSize == 0)
                {
                    yield return processedItems;
                    processedItems.Clear();
                }
            }
            if (processedItems.Count != 0)
            {
                //Because- return the items which are not multiple of chunkSize
                yield return processedItems;
            }
        }
    }

Примечание: результат генерируется за одну итерацию. В этом магия доходности!

0 голосов
/ 25 января 2012

Добавить после первого выбора .Take(3)

...