/// <summary>Takes the top elements as if they were sorted.</summary> /// <typeparam name="TSource">Specifies the type of the elements.</typeparam> /// <typeparam name="TKey">Specifies the type of the keys used to compare elements.</typeparam> /// <param name="source">The source elements.</param> /// <param name="keySelector">A function used to extract a key from each element.</param> /// <param name="count">The number of elements to take.</param> /// <returns></returns> public static IEnumerable <TSource> TakeTop <TSource, TKey>(this ParallelQuery <TSource> source, Func <TSource, TKey> keySelector, int count) { // We want to sort in descending order, so we need the opposite of the default comparer var comparer = new DescendingDefaultComparer <TKey>(); // Aggregate, using a sorted list per thread to keep track of the best N elements, // then merge those at the end. return(source.Aggregate( () => new SortedTopN <TKey, TSource>(count, comparer), (accum, item) => { accum.Add(keySelector(item), item); return accum; }, (accum1, accum2) => { foreach (var item in accum2) { accum1.Add(item); } return accum1; }, (accum) => accum.Values)); }
/// <summary> /// 정렬이 되었다면, 지정된 갯수의 최상위 요소중 <paramref name="count"/> 수만큼 반환합니다. /// </summary> /// <typeparam name="TSource">요소의 수형</typeparam> /// <typeparam name="TKey">요소 비교를 위한 Key의 수형</typeparam> /// <param name="source">요소 집합</param> /// <param name="keySelector">요소로부터 Key를 추출하는 Selector</param> /// <param name="count">취할 요소의 수</param> /// <returns></returns> public static IEnumerable <TSource> TakeTop <TSource, TKey>(this ParallelQuery <TSource> source, Func <TSource, TKey> keySelector, int count = 1) { keySelector.ShouldNotBeNull("keySelector"); if (IsDebugEnabled) { log.Debug("최상의 요소 중 [{0}]만큼 열거합니다.", count); } var comparer = new DescendingDefaultComparer <TKey>(); return (source.Aggregate(() => new SortedTopN <TKey, TSource>(count, comparer), (accum, item) => { accum.Add(keySelector(item), item); return accum; }, (accum1, accum2) => { foreach (var item in accum2) { accum1.Add(item); } return accum1; }, accum => accum.Values)); }
/// <summary>Takes the top elements as if they were sorted.</summary> /// <typeparam name="TSource">Specifies the type of the elements.</typeparam> /// <typeparam name="TKey">Specifies the type of the keys used to compare elements.</typeparam> /// <param name="source">The source elements.</param> /// <param name="keySelector">A function used to extract a key from each element.</param> /// <param name="count">The number of elements to take.</param> /// <returns></returns> public static IEnumerable <TSource> TakeTop <TSource, TKey>(this ParallelQuery <TSource> source, Func <TSource, TKey> keySelector, int count) { DescendingDefaultComparer <TKey> comparer = new DescendingDefaultComparer <TKey>(); return(source.Aggregate <TSource, SortedTopN <TKey, TSource>, IEnumerable <TSource> >(() => new SortedTopN <TKey, TSource>(count, comparer), delegate(SortedTopN <TKey, TSource> accum, TSource item) { accum.Add(keySelector(item), item); return accum; }, delegate(SortedTopN <TKey, TSource> accum1, SortedTopN <TKey, TSource> accum2) { foreach (KeyValuePair <TKey, TSource> pair in accum2) { accum1.Add(pair); } return accum1; }, accum => accum.Values)); }