获取重复的 Arraylist(s),放置在 Arraylist 中的每个索引

Get duplicate Arraylist(s), placed against each index within an Arraylist

例如;

ArraylistRoot (0) > (0): id001
                    (1): 10
                    (2): 20
              (1) > (0):id002
                    (1): 10
                    (2): 20
              (2) > (0):id003
                    (1): 11
                    (2): 20

我需要比较所有子数组列表中的索引 1 和 2 并获取重复记录的 ID,我将使用项目 dll 中的一些函数删除这些记录(这超出了这个问题的范围)。

输出:id001 或 id002(不是两者)

这是我所做的:

ArrayList _tablelist = new ArrayList();
ArrayList _rowList = new ArrayList();
 foreach (cClassInstance _row in GetAllList)
                {
                    var s = _row.GetEnumerator();
                    int count = 0;
                    _rowList.Clear();
                    while (s.MoveNext())
                    {
                        var data = _row.GetRawPropertyValue(count++);
                        _rowList.Add(data);
                    }
                    _tablelist.Insert(_tablelist.Count, new ArrayList(_rowList));
                }

_tableList 包含上例所示的所有数据。

我尝试根据您在问题中分享的数据来实施流程。您仍然可以对此进行优化。我只是想得到结果。

static void Main(string[] args)
{
    // PREPARING SAMPLE DATA   
    List<string> duplicateIds = new List<string>();
    List<List<string>> allItems = new List<List<string>>();

    for (int i = 0; i < 5; i++)
    {
        var items = new List<string>();

        for (int j = 0; j < 3; j++)
        {
            if (j == 0)
                items.Add("id00" + (i + 1));
            else if (i == 2)
                items.Add("" + (j * 11));
            else
                items.Add("" + (j * 10));
        }

        allItems.Add(items);
    }

    //PREPARING OPERATIONAL DATA. COVERTING RAW DATA TO DICTIONARY WHICH KEY IS 0TH ELEMENT (ID)
    var allValues = new Dictionary<string, List<string>>();
    allItems.ForEach(l => allValues.Add(l[0], l.Skip(1).ToList()));

    // FINDING DUPLICATE IDS
    foreach (var key1 in allValues.Keys)
    {
        foreach (var key2 in allValues.Keys)
        {
            if (key1 != key2)
            {
                var diff = allValues[key1].Except(allValues[key2]);

                if (!diff.Any())
                {
                    if (!duplicateIds.Contains(key2))
                        duplicateIds.Add(key2);
                }
            }
        }
    }

    //SORTING DUPLICATE IDS AS NEED TO KEEP FIRST INDEX. REMOVING FIRST ITEM AS NEED TO KEEP THAT ITEM
    //THIS IS MOST IMPORTANT PART OF THIS FLOW
    duplicateIds.Sort();
    duplicateIds = duplicateIds.Skip(1).ToList();

    //DISPLAYING ON CONSOLE
    allItems.ForEach(l => Console.WriteLine(l[0] + "=>" + string.Join(",", l)));
    Console.WriteLine("Duplicate IDs =>" + string.Join(",", duplicateIds));

    Console.ReadLine();
}

假设您总是有两个数字(键串除外),您可以设计自己的自定义数据结构来保存它们。然后,您也可以使用 List 而不是 ArrayList。

例如,

var list = new List<Data>
{
new Data{KeyString="id001",FirstNumber=10,SecondNumber=20},
new Data{KeyString="id002",FirstNumber=10,SecondNumber=20},
new Data{KeyString="id003",FirstNumber=11,SecondNumber=20},
};

其中数据定义为

public class Data
{
    public string KeyString{get;set;}
    public int FirstNumber{get;set;}
    public int SecondNumber{get;set;}
}

您现在可以找到以下副本

var result = list.GroupBy(x=>new {x.FirstNumber,x.SecondNumber}).
                        Where(x=>x.Count()>1);

这将 return 一个 IEnumerable。

如果您只对获取重复项中的第一个 KeyName 感兴趣,可以使用以下方法。

var result = list.GroupBy(x=>new {x.FirstNumber,x.SecondNumber})
                        .Where(x=>x.Count()>1)
                        .Select(x=>x.ToList().Select(c=>c.KeyString).First());

这将 return id001,如 OP 中所述。

对 ArrayLists 非常不满意,如果您必须对这些数据进行大量操作,我当然会按照 Anu 的建议转换为强类型集合。但是使用你所拥有的:

            ArrayList tables = new ArrayList()
            {
                new ArrayList() { "id001", 10, 20 },
                new ArrayList() { "id002", 10, 20 },
                new ArrayList() { "id003", 11, 20 }
            };

            var dupes = tables.ToArray()
                    //collect tables into sets with identical [1] and [2] columns
                    .GroupBy(obj => Tuple.Create(((ArrayList)obj)[1], ((ArrayList)obj)[2]))
                    //filter out any sets with only one member
                    .Where(grp => grp.Count() > 1)
                    //return the column[0] for the first member of each set
                    .Select(grp => ((ArrayList) grp.First())[0])
                    .ToList();