c # сделать элементы списка строк уникальными, добавляя переменное число пробелов - PullRequest
0 голосов
/ 15 ноября 2018

У меня небольшая проблема с алгоритмом, и я застрял в (быстрой) реализации.На самом деле мой незавершенный, но уже замедляет загрузку DataGridView.

Первоначальная проблема: DataGridView WinForms имеет ошибку 2005 года (по-видимому, до сих пор не решена до VS2015), что делает неправильную границу столбцов, имеющих такую ​​жеимя регистра не учитывается.Точнее, если у вас есть 2 столбца «Cat» и «cat», они будут связаны с одним и тем же (первым найденным) объектом в базе данных.

В любом случае, я использую ITypedList и GetItemProperties (), чтобы сообщить DGV о поляхчто я хочу связать.Идея (замеченная где-то в stackoverflow) состоит в том, чтобы добавить пробелы после имени столбцов, «чувствительных к дублированию регистра», например:

"cat"   --> leave as is
"Cat"   --> needs to be come "Cat_"   _ means space
"cAt"   --> needs to become "cAt__"   __ means two spaces and so on

Алгоритм: добавить строки в список с помощью цикла.Перед добавлением проверьте, существует ли строка (обрезается и не учитывается регистр), и если да, добавьте пробел в конец имени.Оставьте имя без изменений в качестве регистра.Другими словами, сделайте строки уникальными, добавив к именам n пробелов.

Надеюсь, я хорошо описал, любая идея приветствуется.

Я провел несколько тестов с моим вариантом и страдает скорость, возможно, такжесделать то, что DGV запускает обратный вызов GetItemProperties () 5 или более раз.

Вот мой код:

   public partial class Form1 : Form
    {

        List<string> list = new List<string>
        {
            "cat",      // the cat
            "Cat",      // first duplicate needs to become Cat_ (one space)
            "kitty",
            "kittY",
            "dog",
            "cAt",      // third duplicate needs to become cAt__ (two spaces)
            "Dog",
            "monkey",
            "monKey",
            "Monkey",
        };

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            AnimalHeaders phList = new AnimalHeaders();

            for (int i = 0; i < list.Count(); i++)
            {
                string field = list.ElementAt(i);

                var caseInsenList = phList.Where(z => z.Name.Trim().Equals(field, StringComparison.OrdinalIgnoreCase));

                int count = caseInsenList.Count();

                if (count == 0) // no results
                {
                    phList.Add(new AnimalHeader { Name = field });
                }
                else // exists but can be many
                {
                    for (j = 0; j < count; j++)
                    {
                        string found = caseInsenList.ElementAt(j).Name.Trim(); // no spaces

                        if (field == found)
                            continue; // exact match, case sensitive, we already have this, skip
                        else
                        {

                        }
                    }

                }
            }

        }
    }


    public class AnimalHeader
    {
        public string Name { get; set; }
        public Type Type { get; set; }
        public int Order { get; set; }

    }

    public class AnimalHeaders : List<AnimalHeader>
    {

    }

1 Ответ

0 голосов
/ 15 ноября 2018

Попробуйте просто Linq : мы группируем одинаковых элементов, а затем добавляем index пробелов (нижних областей) к каждому index -ому элементу в группе. Наконец, мы выравниваем (объединяем) все группы.

  List<string> list = new List<string>() {
    "cat",      // the cat
    "Cat",      // first duplicate needs to become Cat_ (one space)
    "kitty",
    "kittY",
    "dog",
    "cAt",      // third duplicate needs to become cAt__ (two spaces)
    "Dog",
    "monkey",
    "monKey",
    "Monkey",
  };

  List<string> result = list
    .GroupBy(item => item, StringComparer.OrdinalIgnoreCase)
    .SelectMany(chunk => chunk
       .Select((item, index) => string.Format("{0}{1}", item, new string('_', index))))
    .ToList();

Демо-версия:

Console.WriteLine(string.Join(Environment.NewLine, result));

Итог:

cat
Cat_
cAt__
kitty
kittY_
dog
Dog_
monkey
monKey_
Monkey__

Редактировать: В случае, если мы хотим сохранить начальный заказ , мы должны сохранить его (index элемента в начальном списке) и наконец заказ по это:

  List<string> result = list
    .Select((value, index) => new {
      value,
      index
    })
    .GroupBy(item => item.value, StringComparer.OrdinalIgnoreCase)
    .SelectMany(chunk => chunk
       .Select((item, index) => new {
          value = string.Format("{0}{1}", item.value, new string('_', index)),
          index = item.index
        }))
    .OrderBy(item => item.index)
    .Select(item => item.value)
    .ToList();

Итог:

cat
Cat_
kitty
kittY_
dog
cAt__
Dog_
monkey
monKey_
Monkey__
...