Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我如何通过Linq实现它?_C#_Linq - Fatal编程技术网

C# 我如何通过Linq实现它?

C# 我如何通过Linq实现它?,c#,linq,C#,Linq,例如,我有一个类,如下所示: public class SampleItem { public string QCD { get; set; } public string CCD { get; set; } public string ITYPE { get; set; } } 然后,我有一个清单: var lstTest = new List<SampleItem>() { new SampleItem(){ QCD = "Q1" , CC

例如,我有一个类,如下所示:

public class SampleItem
{
    public string QCD { get; set; }
    public string CCD { get; set; }
    public string ITYPE { get; set; }
}
然后,我有一个清单:

var lstTest = new List<SampleItem>() { 

    new SampleItem(){ QCD = "Q1" ,  CCD = "C1" , ITYPE = "A"} ,
    new SampleItem(){ QCD = "Q1" ,  CCD = "C2" , ITYPE = "A"} ,
    new SampleItem(){ QCD = "Q1" ,  CCD = "C3" , ITYPE = "A"} ,

    new SampleItem(){ QCD = "Q1" ,  CCD = "C1" , ITYPE = "B"} ,
    new SampleItem(){ QCD = "Q1" ,  CCD = "C2" , ITYPE = "B"} ,
};
第2组:

new SampleItem(){ QCD = "Q1" ,  CCD = "C1" , ITYPE = "B"} ,
new SampleItem(){ QCD = "Q1" ,  CCD = "C2" , ITYPE = "B"} ,
所以,我只需要

lstTest.GroupBy (p=>new {p.QCD ,p.ITYPE});
但是现在,如果我的列表的顺序与下面的一样

var lstTest = new List<SampleItem>() { 

    new SampleItem(){ QCD = "Q1" ,  CCD = "C1" , ITYPE = "B"} ,
    new SampleItem(){ QCD = "Q1" ,  CCD = "C2" , ITYPE = "B"} ,

    new SampleItem(){ QCD = "Q1" ,  CCD = "C1" , ITYPE = "A"} ,
    new SampleItem(){ QCD = "Q1" ,  CCD = "C2" , ITYPE = "A"} ,
    new SampleItem(){ QCD = "Q1" ,  CCD = "C3" , ITYPE = "A"} ,

    new SampleItem(){ QCD = "Q1" ,  CCD = "C1" , ITYPE = "B"} ,
    new SampleItem(){ QCD = "Q1" ,  CCD = "C2" , ITYPE = "B"} ,
};
第2组:

new SampleItem(){ QCD = "Q1" ,  CCD = "C1" , ITYPE = "A"} ,
new SampleItem(){ QCD = "Q1" ,  CCD = "C2" , ITYPE = "A"} ,
new SampleItem(){ QCD = "Q1" ,  CCD = "C3" , ITYPE = "A"} ,
第3组:

new SampleItem(){ QCD = "Q1" ,  CCD = "C1" , ITYPE = "B"} ,
new SampleItem(){ QCD = "Q1" ,  CCD = "C2" , ITYPE = "B"} ,
通过
LINQ


谢谢你的建议

使用
groupnexting
操作符,例如,可以执行以下操作:

var groupedItems = lstTest.GroupAdjacent(p => new { p.QCD, p.ITYPE });
(现在我发布了,我看到一个类似的
groupnextendent
已经发布,但我将把它作为同一主体的替代实现留在这里)

使用自定义扩展方法,等等:

static void Main() {
    var lstTest = new List<SampleItem>() { 
        new SampleItem(){ QCD = "Q1" ,  CCD = "C1" , ITYPE = "B"} ,
        new SampleItem(){ QCD = "Q1" ,  CCD = "C2" , ITYPE = "B"} ,

        new SampleItem(){ QCD = "Q1" ,  CCD = "C1" , ITYPE = "A"} ,
        new SampleItem(){ QCD = "Q1" ,  CCD = "C2" , ITYPE = "A"} ,
        new SampleItem(){ QCD = "Q1" ,  CCD = "C3" , ITYPE = "A"} ,

        new SampleItem(){ QCD = "Q1" ,  CCD = "C1" , ITYPE = "B"} ,
        new SampleItem(){ QCD = "Q1" ,  CCD = "C2" , ITYPE = "B"} ,
    };
    foreach(var group in lstTest.Split(x => new { x.QCD, x.ITYPE})) {
        Console.WriteLine("{0}, {1}", group[0].QCD, group[0].ITYPE);
        foreach(var item in group) {
            Console.WriteLine("\t{0}", item.CCD);
        }
    }
}
public static IEnumerable<TSource[]> Split<TSource, TValue>(
    this IEnumerable<TSource> source, Func<TSource, TValue> selector)
{
    var comparer = EqualityComparer<TValue>.Default;
    using(var iter = source.GetEnumerator()) {
        if(iter.MoveNext()) {
            List<TSource> buffer = new List<TSource>();
            buffer.Add(iter.Current);
            TValue groupValue = selector(iter.Current);
            while(iter.MoveNext()) {
                var currentItem = iter.Current;
                var currentValue = selector(currentItem);
                if(!comparer.Equals(groupValue, currentValue)) {
                    var arr = buffer.ToArray();
                    buffer.Clear();
                    yield return arr;
                    groupValue = currentValue;
                }
                buffer.Add(currentItem);
            }
            yield return buffer.ToArray();
        }
    }
}
static void Main(){
var lstest=新列表(){
新建SampleItem(){QCD=“Q1”,CCD=“C1”,ITYPE=“B”},
新的SampleItem(){QCD=“Q1”,CCD=“C2”,ITYPE=“B”},
新建SampleItem(){QCD=“Q1”,CCD=“C1”,ITYPE=“A”},
新建SampleItem(){QCD=“Q1”,CCD=“C2”,ITYPE=“A”},
新建SampleItem(){QCD=“Q1”,CCD=“C3”,ITYPE=“A”},
新建SampleItem(){QCD=“Q1”,CCD=“C1”,ITYPE=“B”},
新的SampleItem(){QCD=“Q1”,CCD=“C2”,ITYPE=“B”},
};
foreach(lstest.Split中的var组(x=>new{x.QCD,x.ITYPE})){
WriteLine(“{0},{1}”,组[0]。QCD,组[0]。ITYPE);
foreach(组中的var项目){
WriteLine(“\t{0}”,item.CCD);
}
}
}
公共静态可数分裂(
此IEnumerable源(函数选择器)
{
var comparer=EqualityComparer.Default;
使用(var iter=source.GetEnumerator()){
if(iter.MoveNext()){
列表缓冲区=新列表();
添加缓冲区(iter.Current);
t值组值=选择器(电流);
while(iter.MoveNext()){
var currentItem=额定电流;
var currentValue=选择器(currentItem);
如果(!comparer.Equals(groupValue,currentValue)){
var arr=buffer.ToArray();
buffer.Clear();
收益率;
组值=当前值;
}
buffer.Add(当前项);
}
产生返回缓冲区ToArray();
}
}
}

另一种实现方式:

// name your utility class how you want
public static class MyEnumerable
{
    /// <summary>
    /// Cuts a sequence into groups according to a specified key selector function.
    /// Similar to GroupBy, but only groups adjacent items.
    /// Reduces a collection a,a,B,B,B,a,p,p,p,p to (a,a),(B,B,B),(a),(p,p,p,p).
    /// </summary>
    /// <typeparam name="TSource">The type of the elements of source.</typeparam>
    /// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam>
    /// <param name="source">An <see cref="System.Collections.Generic.IEnumerable"/> whose elements to group.</param>
    /// <param name="keySelector"> A function to extract the key for each element.</param>
    /// <returns>
    /// An IEnumerable&lt;IGrouping&lt;TKey, TSource&gt;&gt; in C# or 
    /// IEnumerable(Of IGrouping(Of TKey, TSource)) in Visual Basic 
    /// where each <see cref="System.Linq.IGrouping"/> 2 object contains  a sequence of objects and a key.
    /// </returns>
    public static IEnumerable<IGrouping<TKey, TSource>> GroupAdjacentBy<TKey, TSource>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
    {
        using (var en = source.GetEnumerator())
        {
            if (!en.MoveNext()) yield break;
            var key = keySelector(en.Current);
            var elements = new List<TSource> { en.Current };
            while (en.MoveNext())
            {
                var nextKey = keySelector(en.Current);
                if (!Equals(nextKey, key))
                {
                    yield return new Grouping<TKey, TSource>(key, elements);
                    key = nextKey;
                    elements = new List<TSource>();
                }
                elements.Add(en.Current);
            }
            yield return new Grouping<TKey, TSource>(key, elements);
        }
    }
返回包含

  • 3:1
  • 5:7,强制
  • 3:哇,再见

那么,只要值发生变化,它就会被拆分,而不是一个完整的组-没有内置的LINQ操作;您必须手动编写它。我稍后会尝试一下…谢谢你的评论,是的,我已经通过循环实现了它。但是,实际上这只是我代码的一部分。我想找到一个更清楚的方法来解决这个问题在第二种情况下,第一组和第三组是相同的。对于多个组,有些事情应该是不同的。@V4Vendetta是的,示例为Group3。这只是一个示例,但它是可用的。因此,类似于对连续项进行分组,这样的实现可能是对Cadenza的一个有趣的补充
static void Main() {
    var lstTest = new List<SampleItem>() { 
        new SampleItem(){ QCD = "Q1" ,  CCD = "C1" , ITYPE = "B"} ,
        new SampleItem(){ QCD = "Q1" ,  CCD = "C2" , ITYPE = "B"} ,

        new SampleItem(){ QCD = "Q1" ,  CCD = "C1" , ITYPE = "A"} ,
        new SampleItem(){ QCD = "Q1" ,  CCD = "C2" , ITYPE = "A"} ,
        new SampleItem(){ QCD = "Q1" ,  CCD = "C3" , ITYPE = "A"} ,

        new SampleItem(){ QCD = "Q1" ,  CCD = "C1" , ITYPE = "B"} ,
        new SampleItem(){ QCD = "Q1" ,  CCD = "C2" , ITYPE = "B"} ,
    };
    foreach(var group in lstTest.Split(x => new { x.QCD, x.ITYPE})) {
        Console.WriteLine("{0}, {1}", group[0].QCD, group[0].ITYPE);
        foreach(var item in group) {
            Console.WriteLine("\t{0}", item.CCD);
        }
    }
}
public static IEnumerable<TSource[]> Split<TSource, TValue>(
    this IEnumerable<TSource> source, Func<TSource, TValue> selector)
{
    var comparer = EqualityComparer<TValue>.Default;
    using(var iter = source.GetEnumerator()) {
        if(iter.MoveNext()) {
            List<TSource> buffer = new List<TSource>();
            buffer.Add(iter.Current);
            TValue groupValue = selector(iter.Current);
            while(iter.MoveNext()) {
                var currentItem = iter.Current;
                var currentValue = selector(currentItem);
                if(!comparer.Equals(groupValue, currentValue)) {
                    var arr = buffer.ToArray();
                    buffer.Clear();
                    yield return arr;
                    groupValue = currentValue;
                }
                buffer.Add(currentItem);
            }
            yield return buffer.ToArray();
        }
    }
}
// name your utility class how you want
public static class MyEnumerable
{
    /// <summary>
    /// Cuts a sequence into groups according to a specified key selector function.
    /// Similar to GroupBy, but only groups adjacent items.
    /// Reduces a collection a,a,B,B,B,a,p,p,p,p to (a,a),(B,B,B),(a),(p,p,p,p).
    /// </summary>
    /// <typeparam name="TSource">The type of the elements of source.</typeparam>
    /// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam>
    /// <param name="source">An <see cref="System.Collections.Generic.IEnumerable"/> whose elements to group.</param>
    /// <param name="keySelector"> A function to extract the key for each element.</param>
    /// <returns>
    /// An IEnumerable&lt;IGrouping&lt;TKey, TSource&gt;&gt; in C# or 
    /// IEnumerable(Of IGrouping(Of TKey, TSource)) in Visual Basic 
    /// where each <see cref="System.Linq.IGrouping"/> 2 object contains  a sequence of objects and a key.
    /// </returns>
    public static IEnumerable<IGrouping<TKey, TSource>> GroupAdjacentBy<TKey, TSource>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
    {
        using (var en = source.GetEnumerator())
        {
            if (!en.MoveNext()) yield break;
            var key = keySelector(en.Current);
            var elements = new List<TSource> { en.Current };
            while (en.MoveNext())
            {
                var nextKey = keySelector(en.Current);
                if (!Equals(nextKey, key))
                {
                    yield return new Grouping<TKey, TSource>(key, elements);
                    key = nextKey;
                    elements = new List<TSource>();
                }
                elements.Add(en.Current);
            }
            yield return new Grouping<TKey, TSource>(key, elements);
        }
    }
new[]{"one","seven","force","wow","bye"}.GroupAdjecent(s=>s.Length)