按元素拆分列表

科森科夫

我有1和0这样的列表:

var list = new List<int>{1,1,1,0,1,1,0,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1}

在两个项目之间,只能是一个零。如何将该列表分成0个子列表?

换句话说:如果我有这样的字符串:string myString = "111011011110111111011101"则很容易将其以0拆分为几个字符串。但是如何使用列表呢?此示例将生成以下子列表:

1,1,1
1,1
1,1,1,1
1,1,1,1,1,1
1,1,1
1

所以有什么更好的方法,然后将每个元素转换为字符串,将它们连接起来,然后执行我所展示的使用string可以完成的工作?

马丁·利弗塞奇

您可以像LINQ一样通过将输入序列转换为序列序列来解决问题GroupBy但是,根据您的情况,您要对输入顺序的更改进行分组。有可能是现有的LINQ运营商合并同类的可能性GroupByZipSkip到的东西,你想要做什么,但我认为它更容易(和性能更好)来创建一个迭代器块,着眼于对输入序列中的项目:

static class EnumerableExtensions {

  public static IEnumerable<IEnumerable<T>> GroupOnChange<T>(
    this IEnumerable<T> source,
    Func<T, T, Boolean> changePredicate
  ) {
    if (source == null)
      throw new ArgumentNullException("source");
    if (changePredicate == null)
      throw new ArgumentNullException("changePredicate");

    using (var enumerator = source.GetEnumerator()) {
      if (!enumerator.MoveNext())
        yield break;
      var firstValue = enumerator.Current;
      var currentGroup = new List<T>();
      currentGroup.Add(firstValue);
      while (enumerator.MoveNext()) {
        var secondValue = enumerator.Current;
        var change = changePredicate(firstValue, secondValue);
        if (change) {
          yield return currentGroup;
          currentGroup = new List<T>();
        }
        currentGroup.Add(secondValue);
        firstValue = secondValue;
      }
      yield return currentGroup;
    }
  }

}

GroupOnChange将采用输入序列中的项目并将它们分组为一系列序列。如果changePredicate为true,则开始一个新组

您可以用来GroupOnChange完全按需分割输入序列。然后,您必须使用删除值为零的组Where

var groups = items
  .GroupOnChange((first, second) => first != second)
  .Where(group => group.First() != 0);

如果输入是类实例,并且要按该类的属性分组,则也可以使用此方法。然后,您必须相应地修改谓词以比较属性。(我知道您需要这个,因为您问了一个现在删除的问题,该问题稍微复杂一点,其中输入序列不仅仅是数字,而是具有数字属性的类。)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章