从IEnumerable返回数据

时间:2015-03-04 10:46:01

标签: linq c#-4.0 collections lambda

考虑,

public class Obj
{
     public string PropertyName;
     public string Name;
     public int Id;
     public int Value;
}

List<Obj> lsObjdata = new List<Obj>();
var obj  = new Obj { Name = "xyz", PropertyName = "Volume", Id= 1, Value = 25};
lsObjdata.Add(obj);
obj  = new Obj { Name = "abc", PropertyName = "Volume", Id= 1, Value = 23};
lsObjdata.Add(obj);
obj = new Obj {Name = "abc", PropertyName = "Oil", Id =1, Value = 45};
lsObjdata.Add(obj);

IEnumerable<IGrouping<String, obj>> results = lsObjData.GroupBy( m => m.Id);

现在,我的results将为同一个id提供3个值。我的商家要求我优先考虑以xyz作为名称的obj,如果属性匹配则省略另一个。但是,如果xyz没有abc具有的属性?获取该属性的值。就像上面给出的第三个对象的初始化一样。

obj = new {Name = "abc", PropertyName = "Oil", Id =1, Value = 45}

此属性和值不存在,名称为xyz。这应该添加到我的最终输出中。我的结果应该包含列表中的以下对象。

obj = new {Name = "abc", PropertyName = "Oil", Id =1, Value = 45}
obj  = new { Name = "xyz", PropertyName = "Volume", Id= 1, Value = 25};

PS:我已经完成了解决方案。 但是,我无法使用Linq / Lambda表达式并在单行/笔划中获得解决方案。 谁可以在这方面帮助我? 谢谢, 萨姆

2 个答案:

答案 0 :(得分:1)

您需要按两个属性分组 - Id, PropertyName,然后通过按以下方式排序分组数据来选择第一个对象: -

var results = lsobjdata.GroupBy(x => new { x.Id, x.PropertyName })
                        .Select(x => x.OrderByDescending(z => z.Name).FirstOrDefault());

以下是包含一些示例数据的Working Fiddle

答案 1 :(得分:1)

因为你没有提到你想要每个结果集的第一个。我正在提供另一种解决方案。

// Define other methods and classes here
public class Obj
{
    public string PropertyName;
    public string Name;
    public int Id;
    public int Value;
}

public class Key
{
    public string PropertyName;
    public int Id;

    public override bool Equals(object obj)
    {
    Key item = obj as Key;

        return item.Id == this.Id && item.PropertyName == this.PropertyName;
    }

    public override int GetHashCode()
    {
        int hash = 13;
        hash = (hash * 7) + Id.GetHashCode();
        hash = (hash * 7) + PropertyName.GetHashCode();
        return hash;
    }
}

void static Main()
{
    List<Obj> lsObjdata = new List<Obj>();
    HashSet<Key>  keys = new HashSet<Key>();
    var obj  = new Obj { Name = "xyz", PropertyName = "Volume", Id= 1, Value = 25};
    lsObjdata.Add(obj);
    obj  = new Obj { Name = "abc", PropertyName = "Volume", Id= 1, Value = 23};
    lsObjdata.Add(obj);
    obj = new Obj {Name = "abc", PropertyName = "Oil", Id =1, Value = 45};
    lsObjdata.Add(obj);
    obj = new Obj {Name = "abc", PropertyName = "Gas", Id =1, Value = 45};
    lsObjdata.Add(obj);
    obj = new Obj {Name = "edf", PropertyName = "Gas", Id =1, Value = 45};
    lsObjdata.Add(obj);
    var results = lsObjdata.GroupBy(m => new Key { Id = m.Id, PropertyName = m.PropertyName })
                                .Select<IGrouping<Key,Obj>,IEnumerable<Obj>>(x =>
                                {
                                    if (x.Any(v => v.Name == "xyz") && !keys.Contains(x.Key))
                                    {
                                            return new Obj[]{x.First(v => v.Name == "xyz")};
                                    }
                                    else if (!keys.Contains(x.Key as Key))
                                    {
                                            return x.Select(v=>v);                                      
                                    }
                                    else
                                        return null;
                                })
                                .SelectMany(x=>x)
                                .Where(x=> x != null);

    foreach (var res in results)
    {

            Console.WriteLine(res.PropertyName + "  "+res.Name+"  "+res.Id+"  "+ res.Value);
    }

    Console.WriteLine(results);
}

enter image description here