Получите дубликаты Arraylist (s), расположенные против каждого индекса в Arraylist - PullRequest
0 голосов
/ 15 февраля 2019

например;

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

Мне нужно сравнить индексы 1 и 2 среди всех субаррайлистов и получить идентификаторы дубликатов записей, которые я должен удалить, используя некоторые функции из 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 Содержит все данные, как показано вприведенный выше пример.

Ответы [ 3 ]

0 голосов
/ 15 февраля 2019

Предполагая, что у вас всегда есть два числа (кроме строки ключей), вы можете создать собственную структуру данных для их хранения.И тогда вместо ArrayList вы также можете использовать List.

Например,

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},
};

Где Data определяется как

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);

Это вернет 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());

Это вернет id001, как описано в OP.

0 голосов
/ 15 февраля 2019

Довольно неприятно с 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();
0 голосов
/ 15 февраля 2019

Я пытался реализовать поток на основе данных, которые вы поделились в вашем вопросе.Вы все еще можете оптимизировать это.Я просто пытаюсь получить результаты.

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();
}
...