如何平均划分可观察的集合

时间:2018-01-22 16:37:59

标签: c#

我想平均分割'tar'集合。我有6个单独的集合,我想在6个列表中均匀填充它们,无论集合的大小 例如,如果有23个项目,则6个列表应为4,4,4,4,4,最后3个或24个:4,4,4,4,4和4

ObservableCollection<test> tar = new ObservableCollection<test>();
        tar.Add(new test { name="a"});
        tar.Add(new test { name = "b" });
        tar.Add(new test { name = "c" });
        tar.Add(new test { name = "d" });
        tar.Add(new test { name = "e" });
        tar.Add(new test { name = "f" });
        tar.Add(new test { name = "g" });
        tar.Add(new test { name = "h" });
        tar.Add(new test { name = "i" });
        tar.Add(new test { name="ae"});
        tar.Add(new test { name = "br" });
        tar.Add(new test { name = "cwr" });
        tar.Add(new test { name = "dt" });
        tar.Add(new test { name = "ef" });
        tar.Add(new test { name = "ff" });
        tar.Add(new test { name = "fg" });
        tar.Add(new test { name = "hg" });
        tar.Add(new test { name = "ie" });

我尝试过这个功能,我发现只是但不确定如何访问这些组。

    ObservableCollection<ObservableCollection<test>> Split(ObservableCollection<test> collection, int splitBy = 3)
    {

        var result = collection
                   .Select((x, i) => new { index = i, item = x })
                   .GroupBy(x => x.index / splitBy, x => x.item)
                   .Select(g => new ObservableCollection<test>(g));
        return new ObservableCollection<ObservableCollection<test>>(result);
    }

1 个答案:

答案 0 :(得分:0)

你的情况听起来很像我写的批量扩展。 它采用一个集合并返回拆分为指定大小批次的那些项目的新集合。返回集合中的最后一个批次将包含剩余项目,因此它将没有其他项目,您可以修改此代码来执行此操作,我现在也将处理它(在下面编辑)。 / p>

public static IEnumerable<IEnumerable<TSource>> Batch<TSource>(this IEnumerable<TSource> items, int size)
{
    return items.Batch(size, x => x);
}

public static IEnumerable<TResult> Batch<TSource, TResult>(this IEnumerable<TSource> items, int size, 
    Func<IEnumerable<TSource>, TResult> selector)
{
    if (items == null)
        throw new ArgumentException(nameof(items));
    if (size <= 0)
        throw new ArgumentOutOfRangeException(nameof(size));
    if (selector == null)
        throw new ArgumentNullException(nameof(selector));

    using (var enumerator = items.GetEnumerator())
    {
        var taken = 0;
        while (enumerator.MoveNext())
        {
            yield return selector(items.Skip(taken)
                .Take(size));
            for (int i = 0; i < size - 1; i++)
                if (!enumerator.MoveNext())
                    break;
            taken += size;
        }
    }
}

修改:以下对批量扩展的修改对我有用。您可能希望以不同的方式实现它,具体取决于您希望如何填充最后一批。我这样做的方法是使用TSource的默认值,对于你来说,测试默认为null。

while (enumerator.MoveNext())
{
    IEnumerable<TSource> batch;
    batch = items.Skip(taken).Take(size);
    var count = items.Count();
    if (taken + size >= count)
        batch = batch.Concat(Enumerable.Range(0, count - taken)
            .Select(i => default(TSource)));
    yield return selector(batch);
    for (int i = 0; i < size - 1; i++)
        if (!enumerator.MoveNext())
            break;
    taken += size;
}