2

次のコレクションを検討してください。

  • 真実
  • 間違い
  • 間違い
  • 間違い
  • 真実
  • 真実
  • 間違い
  • 間違い

構造化された方法で表示したい、たとえばTreeView. グループ全体などに境界線を引きたいと思っています。

  • 真のグループ
    • 真実
  • 偽グループ
    • 間違い
    • 間違い
    • 間違い
  • 真のグループ
    • 真実
    • 真実
  • 偽グループ
    • 間違い
    • 間違い

できるだけ少ない手続き型コードでこれを達成するにはどうすればよいですか?

4

5 に答える 5

5

これはあなたが探していることを行い、一般的です:

private static IEnumerable<IGrouping<int, T>> GroupConsecutive<T>(this IEnumerable<T> set, Func<T, T, bool> predicate)
{
    var i = 0;
    var k = 0;
    var ranges = from e in set
                 let idx = ++i
                 let next = set.ElementAtOrDefault(idx)
                 let key = (predicate(e, next)) ? k : k++
                 group e by key into g
                 select g;
    return ranges;
}

使用法:

var set = new List<bool>
            {
                true,
                false,
                false,
                false,
                true,
                true,
                false,
                false,
            };
var groups = set.GroupConsecutive((b1, b2) => (b1 == b2));
foreach (var g in groups)
{
    Console.WriteLine(g.Key);
    foreach (var b in g)
        Console.WriteLine("\t{0}", b);
}

出力:

0
        True
1
        False
        False
        False
2
        True
        True
3
        False
        False
于 2010-03-27T04:43:36.330 に答える
0

受け入れられた回答のコードは元の質問のニーズを満たしていますが、より複雑なオブジェクトの IEnumerables を処理するときにフォールオーバーします (列挙型の最後の項目を「次の」項目と比較するときに、述語が例外をスローする傾向があるため) [定義により、常に null になります])。

このバージョンは、より複雑なオブジェクトを処理します:

   public static IEnumerable<IGrouping<int, T>> GroupConsecutive<T>(this IEnumerable<T> set, Func<T, T, bool> predicate)
    {
        var i = 0;
        var k = 0;
        var ranges = from e in set
                     let idx = ++i
                     let next = set.ElementAtOrDefault(idx)
                     let key = next == null ? k : (predicate(e, next)) ? k : k++
                     group e by key into g
                     select g;
        return ranges;
    } 
于 2014-11-03T12:18:33.637 に答える
-1
public class GroupConsecutiveEqualItemsConverter : IValueConverter
{
    static readonly object UnsetValue = new object();

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        IEnumerable source = value as IEnumerable;
        if (source == null) return DependencyProperty.UnsetValue;
        string propertyName = parameter as string;
        var result = new ObservableCollection<List<object>>();

        var notify = value as INotifyCollectionChanged;
        if (notify != null) notify.CollectionChanged += delegate { Reload(result, source, propertyName); };

        Reload(result, source, propertyName);
        return result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }

    void Reload(ObservableCollection<List<object>> result, IEnumerable source, string propertyName)
    {
        result.Clear();
        object previous = UnsetValue;
        List<object> group = null;
        foreach (object i in source)
        {
            object current = UnsetValue;
            if (propertyName == null)
            {
                current = i;
            }
            else
            {
                try
                {
                    var property = i.GetType().GetProperty(propertyName);
                    if (property != null) current = property.GetValue(i, null);
                }
                catch (AmbiguousMatchException) { }
            }
            if (!object.Equals(previous, current))
            {
                if (group != null) result.Add(group);
                group = new List<object>();
            }
            group.Add(i);
            previous = current;
        }
        if (group != null && group.Count > 0) result.Add(group);
    }
}
于 2009-09-25T18:26:55.187 に答える
-1
last = null;
foreach (var option in list)
{
   if (last != option)
      newlist.Add(new Group(option, new[]));
   newlist.Last().Add(option);
   last = option;
}
于 2009-09-25T15:54:37.597 に答える