1

私はint配列を持っています。これは、すべて1から始まる複数の同様の配列から連結された配列です。

1, 2, 3, 4
1, 2
1, 2, 3
1, 2

int[] list = { 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 2 };

私が達成しようとしているのは、{1, 2} である結果の「最後のセット」を取得することです。

試行:

int[] list = { 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 2 };

List<int> lastSet = new List<int>();
var totalSets = list.Count(x => x == 1);

int encounter = 0;
foreach (var i in list)
{
    if (i == 1)
        encounter += 1;

    if (encounter == totalSets)
        lastSet.Add(i);
}

lastSet.ToList().ForEach(x => Console.WriteLine(x));

SkipWhileおそらくLINQを使用してこれGroupByを達成するより良い方法はありAggregateますか?

4

4 に答える 4

1

リストを実際のものにすることができる場合、List<int>またはを介してリストのコピーを作成するのが面倒でない場合は、次の.ToList()ようにすることができます。

var list = new[]{ 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 2 }.ToList();
var lastSet = list.Skip(list.LastIndexOf(1)).ToList();

そうでなければ、Aggregate動作することができますが、それは少し醜いです:

var lastSet = list.Aggregate(new List<int>{1}, (seed, i) => {
    if(i == 1) {seed.Clear(); }
    seed.Add(i);
    return seed;
})

アップデート

dtbが指摘しているように、リストを作成する代わりにArray.LastIndexOfを使用できます。

var list = new[]{ 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 2 };
var lastSet = list.Skip(Array.LastIndexOf(list, 1)).ToList();
于 2012-05-11T02:54:38.210 に答える
1

任意で動作します(ただし、直接バージョンIEnumerableよりも遅くなります)List

var sub = list.Reverse<int>()
              .TakeWhile(i => i != 1)
              .Concat(new[]{1})
              .Reverse<int>();

ToArray()必要に応じて、結果に対してa を実行します。

于 2012-05-11T02:57:28.913 に答える
1

以下のGroupAdjacent 拡張メソッドを使用すると、リストを 1 で始まるシーケンスに分割し、最後のシーケンスを取ることができます。

var result = list.GroupAdjacent((g, x) => x != 1)
                 .Last()
                 .ToList();

public static IEnumerable<IEnumerable<T>> GroupAdjacent<T>(
    this IEnumerable<T> source, Func<IEnumerable<T>, T, bool> adjacent)
{
    var g = new List<T>();
    foreach (var x in source)
    {
        if (g.Count != 0 && !adjacent(g, x))
        {
            yield return g;
            g = new List<T>();
        }
        g.Add(x);
    }
    yield return g;
}
于 2012-05-11T02:58:31.737 に答える
1

LINQ は過大評価されています。

int[] list = { 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 2 };

int pos = Array.LastIndexOf(list, 1);

int[] result = new int[list.Length - pos];
Array.Copy(list, pos, result, 0, result.Length);

// result == { 1, 2 }

100% 読みやすくなりました:

int[] list = { 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 2 };

int[] result = list.Slice(list.LastIndexOf(1));

// result == { 1, 2 }

どこ

static int LastIndexOf<T>(this T[] array, T value)
{
    return Array.LastIndexOf<T>(array, value);
}

static T[] Slice<T>(this T[] array, int offset)
{
    return Slice(array, offset, array.Length - offset);
}

static T[] Slice<T>(this T[] array, int offset, int length)
{
    T[] result = new T[length];
    Array.Copy(array, offset, result, 0, length);
    return result;
}
于 2012-05-11T03:13:40.993 に答える