根据数据顺序进行分组

时间:2015-04-25 18:43:42

标签: c# sql .net linq

我有以下格式的一组数据。

A
A
B
A
C
B
B
C

我想以这样一种方式对数据进行分组,即结果应按字母顺序分组,并且应该基于顺序。例如,对于上述数据,输出应为

A - 2
B - 1
A - 1
C - 1
B - 2
C - 1

4 个答案:

答案 0 :(得分:0)

创建变量以跟踪最后一个字母和计数。然后循环遍历字母并在字母发生变化时发出数据。

List<char> letters = new List<char>() { 'A', 'A', 'B', 'A', 'C', 'B', 'B', 'C' };

char last = letters.First();
int count = 1;
foreach (char letter in letters.Skip(1))
{
    if (letter == last)
    {
        count++;
    }
    else
    {
        Console.WriteLine(last + " - " + count);
        last = letter;
        count = 1;
    }
}
Console.WriteLine(last + " - " + count);

第一个字符是通过设置last = letters.First()在循环外处理的,因此foreach循环以第二个字符开头,调用letters.Skip(1)

最后一个Console.WriteLine用于处理最终的字符块。

答案 1 :(得分:0)

有一个很好的LINQ扩展来做你想要的,由Eric White创建。您可以使用以下扩展方法来获得邻接分组:

 public static class LINQExtensions
{
    public static IEnumerable<IGrouping<TKey, TElement>> GroupAdjacentBy<TElement, TKey>(this IEnumerable<TElement> source, Func<TElement, TKey> keySelector, IEqualityComparer<TKey> comparer = null)
    {
        comparer = comparer ?? EqualityComparer<TKey>.Default;
        List<TElement> elements = null;
        TKey key = default(TKey);
        TKey lastKey = default(TKey);
        foreach (var x in source)
        {
            key = keySelector(x);
            if (elements != null && elements.Any() && !comparer.Equals(lastKey, key))
            {
                yield return new Grouping<TKey, TElement>(lastKey, elements);
                elements = null;
            }
            if (elements == null)
            {
                elements = new List<TElement>();
                lastKey = key;
            }
            elements.Add(x);
        }
        if (elements != null && elements.Any())
        {
            yield return new Grouping<TKey, TElement>(key, elements);
        }
    }

    public static IEnumerable<IGrouping<TElement, TElement>> GroupAdjacentBy<TElement>(this IEnumerable<TElement> source, IEqualityComparer<TElement> comparer = null)
    {
        return source.GroupAdjacentBy(keySelector: x => x, comparer: comparer);
    }

    // implement IGrouping
    public class Grouping<TKey, TElement> : IGrouping<TKey, TElement>
    {
        public TKey Key { get; private set; }
        private List<TElement> Elements { get; set; }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return ((IEnumerable<TElement>)this).GetEnumerator();
        }
        IEnumerator<TElement> IEnumerable<TElement>.GetEnumerator()
        {
            return ((IEnumerable<TElement>)Elements).GetEnumerator();
        }
        public Grouping(TKey key, List<TElement> elements)
        {
            Key = key;
            Elements = elements;
        }
    }
}

对于驱动程序,请考虑以下事项:

    class Program
{
    static void Main(string[] args)     
     {
        List<String> list = new List<string>() { "A", "A", "B", "B", "B", "A", "A", "A"};
        var groups = list.GroupAdjacentBy(x => x);

        foreach(var group in groups)
            Console.WriteLine(string.Format("Key: {0}, Count: {1}", group.Key, group.Count()));

        Console.ReadLine();
     }

}

Try it out at IDEOne

输出大致是:

Key: A, Count: 2
Key: B, Count: 3
Key: A, Count: 3

答案 2 :(得分:0)

这是我尝试以更多功能的方式(尽管不是很成功)。当前一个元素不等于当前元素时,我们的想法是按标准增加gorup:

    class ElementWithGroup
    {
        public string Element { get; set; }
        public int Index { get; set; }
        public int Group { get; set; }
    }

    static void Main(string[] args)
    {
        var list = new List<string>
        {
            "A",
            "A",
            "B",
            "A",
            "C",
            "B",
            "B",
            "C"
        };

        var helpList = list
            .Select((e, i) => new ElementWithGroup { Element = e, Index = i, Group = 0 })
            .ToList();

        var result = helpList
            .GroupBy(e => {
                var previous = e.Index == 0 ? null : helpList.ElementAt(e.Index - 1);
                if (previous != null)
                {
                    e.Group = previous.Element == e.Element ? previous.Group : previous.Group + 1;
                }
                return e.Group;
            });
    }

我对这个解决方案不满意,我宁愿以迭代的方式做到这一点,但也许它会帮助某人。

答案 3 :(得分:0)

试试这个:

{
"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Action": "s3:ListAllMyBuckets",
        "Resource": "arn:aws:s3:::*"
    },
    {
        "Effect": "Allow",
        "Principal": "*",
        "Action": [
            "s3:Get*",
            "s3:List*"
        ],
        "Resource": [
            "arn:aws:s3:::myBucket/*",
            "arn:aws:s3:::myBucket"
        ]
    }
]
}