多个列表中的不常见元素

时间:2013-06-05 02:38:18

标签: c# linq list hashset

我有多个列表,我想在每个列表中找到不同的不常见元素。

我来到了一个点,但无法设法得到不常见的元素,但最终得到了共同的元素。

以下是代码:

private void button1_Click(object sender, EventArgs e)
    {
        List<DataTable> dataTables = new List<DataTable>();

        List<string> c = new List<string>();
        c.Add("A");
        c.Add("B");
        c.Add("C");
        dataTables.Add(ss(c));            
        c.Add("B");
        c.Add("C");
        dataTables.Add(ss(c));
        c.Add("A");
        c.Add("B");
        dataTables.Add(ss(c));


        var setsOfIds = dataTables.Select(t => t.AsEnumerable().Select(x => x.Field<string>("ELIGIBLE")).OfType<string>());                        
        var commonIds = IntersectAll<string>(setsOfIds);
        var rows = dataTables.SelectMany(t => t.AsEnumerable()).Where(r => commonIds.Contains(r.Field<string>("ELIGIBLE")));
        var resultRows = rows.GroupBy(r => r.Field<string>("TEDARIKCI")).Select(r => r.First());

    }

    private DataTable ss(List<string> aa)
    {
        DataTable dt = new DataTable("x");
        dt.Columns.Add("ELIGIBLE", typeof(string));
        DataRow dr = null;//= dt.NewRow();

        foreach (string item in aa)
        {
            dr = dt.NewRow();
            dr[0] = item;
            dt.Rows.Add(dr);
        }

        return dt;
    }

    public List<T> IntersectAll<T>(IEnumerable<IEnumerable<T>> lists)
    {
        HashSet<T> hashSet = null;
        foreach (var list in lists)
        {
            if (hashSet == null)
            {
                hashSet = new HashSet<T>(list);                    
            }
            else
            {
                hashSet.IntersectWith(list);
            }
        }
        return hashSet == null ? new List<T>() : hashSet.ToList();
    }

IntersectAll对我没有帮助,因为它给了我A,B,C。但我只想要B(每个列表都是通用的)

如果s.o.我会很感激。可以提供样品。这真让我抓狂!! Pleeeeaaseeee

3 个答案:

答案 0 :(得分:2)

var l1 = new List<string> {"A", "B", "C", "D"};
var l2 = new List<string> {"B", "C", "E"};
var l3 = new List<string> {"A", "B"};

var c = l1.Intersect(l2).Intersect(l3);

返回“B”

var uc1= l1.Except(l2).Except(l3);
var uc2= l2.Except(l1).Except(l3);
var uc3= l3.Except(l1).Except(l2);
var uc=uc1.Union(uc2).Union(uc3);

应该给:

uc1 = "D"
uc2 = "E"
uc3 = {empty}
uc = "D","E"

答案 1 :(得分:1)

你想要的并不完全清楚。您似乎要求一种方法来查找仅出现在一个列表中的元素(没有两个列表共有它们),但您的预期结果似乎建议您要查找ALL列表共有的元素。无论如何,Linq都很容易。

这将找到在所有列表中只出现一次的所有元素:

public IEnumerable<T> FindUniques<T>(IEnumerable<IEnumerable<T>> lists)
{
    return lists.SelectMany(x => x).GroupBy(x => x)
                .Where(g => !g.Skip(1).Any())
                .Select(g => g.First());
}

此填充查找每个列表中显示的所有元素:

public IEnumerable<T> IntersectAll<T>(IEnumerable<IEnumerable<T>> lists)
{
    return lists.Aggregate((a, x) => a.Intersect(x));
}

例如:

var list1 = new[] { "A", "B", "C" };
var list2 = new[] { "B", "C", "D" };
var list3 = new[] { "C", "D", "E" };

FindUniques(new[] { list1, list2, list3 }); // { "A", "E" }
IntersectAll(new[] { list1, list2, list3 }); // { "C" }

答案 2 :(得分:1)

在您的代码中,第一个列表包含3个元素(ABC),第二个列表包含5(ABCBC),第三个列表包含7(ABCBCAB)。

换句话说,所有列表都有A, B, C ..

在添加到new之前创建List dataTable可以解决此问题

        List<DataTable> dataTables = new List<DataTable>();

        List<string> c = new List<string>();
        c.Add("A");
        c.Add("B");
        c.Add("C");
        dataTables.Add(ss(c));

        List<string> c2 = new List<string>();//New List
        c2.Add("B");
        c2.Add("C");
        dataTables.Add(ss(c2));

        List<string> c3 = new List<string>();//New List
        c3.Add("A");
        c3.Add("B");
        dataTables.Add(ss(c3));

        var setsOfIds = dataTables.Select(t => t.AsEnumerable().Select(x => x.Field<string>("ELIGIBLE")).OfType<string>());                        
        var commonIds = IntersectAll<string>(setsOfIds);

此处commonIds列表只包含一个元素B