#region License Information
/* HeuristicLab
* Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
namespace HeuristicLab.Common {
public static class EnumerableExtensions {
///
/// Selects all elements in the sequence that are maximal with respect to the given value.
///
///
/// Runtime complexity of the operation is O(N).
///
/// The type of the elements.
/// The enumeration in which the items with a maximal value should be found.
/// The function that selects the value to compare.
/// All elements in the enumeration where the selected value is the maximum.
public static IEnumerable MaxItems(this IEnumerable source, Func valueSelector) {
IEnumerator enumerator = source.GetEnumerator();
if (!enumerator.MoveNext()) return Enumerable.Empty();
IComparable max = valueSelector(enumerator.Current);
var result = new List();
result.Add(enumerator.Current);
while (enumerator.MoveNext()) {
T item = enumerator.Current;
IComparable comparison = valueSelector(item);
if (comparison.CompareTo(max) > 0) {
result.Clear();
result.Add(item);
max = comparison;
} else if (comparison.CompareTo(max) == 0) {
result.Add(item);
}
}
return result;
}
///
/// Selects all elements in the sequence that are minimal with respect to the given value.
///
///
/// Runtime complexity of the operation is O(N).
///
/// The type of the elements.
/// The enumeration in which items with a minimal value should be found.
/// The function that selects the value.
/// All elements in the enumeration where the selected value is the minimum.
public static IEnumerable MinItems(this IEnumerable source, Func valueSelector) {
IEnumerator enumerator = source.GetEnumerator();
if (!enumerator.MoveNext()) return Enumerable.Empty();
IComparable min = valueSelector(enumerator.Current);
var result = new List();
result.Add(enumerator.Current);
while (enumerator.MoveNext()) {
T item = enumerator.Current;
IComparable comparison = valueSelector(item);
if (comparison.CompareTo(min) < 0) {
result.Clear();
result.Add(item);
min = comparison;
} else if (comparison.CompareTo(min) == 0) {
result.Add(item);
}
}
return result;
}
///
/// Compute the n-ary cartesian product of arbitrarily many sequences: http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx
///
/// The type of the elements inside each sequence
/// The collection of sequences
/// An enumerable sequence of all the possible combinations of elements
public static IEnumerable> CartesianProduct(this IEnumerable> sequences) {
IEnumerable> result = new[] { Enumerable.Empty() };
return sequences.Where(s => s.Any()).Aggregate(result, (current, s) => (from seq in current from item in s select seq.Concat(new[] { item })));
}
}
}