У меня есть список строк, сгенерированный программно следующим образом:
var list = new List<string>
{
"anonim",
"anonim şirket",
"anonim şirketler",
"tapu",
"tapu senedi",
"tapu kütüğü",
"yaptırım",
"müeyyide",
"işçi",
"işçi alacakları",
"işçi hakları",
"işçi lehine yorum ilkesi",
"işçilik sözleşmesi",
"limited şirket",
"sınırlı ayni hak",
"telif hakkı",
"unutulma hakkı",
"yolsuz tescil",
"zamanaşımı"
};
Он содержит множество повторяющихся однородных элементов. Поэтому я подумал, что проигнорирую это с помощью словаря. Если в списке существует ключ словаря, я хочу игнорировать элементы, разделенные запятыми, в значении словаря. Вот словарь:
var dict = new Dictionary<string, string>
{
{"anonim şirket", "anonim, anonim şirketler"},
{"tapu senedi", "tapu, tapu kütüğü"},
{"yaptırım", "müeyyide"},
{"işçi hakları", "işçi, işçi alacakları, işçi lehine yorum ilkesi, işçilik sözleşmesi"}
};
Итак, окончательный список, который я хочу получить, выглядит следующим образом:
var new_list = new List<string>()
{
"anonim şirket",
"tapu senedi",
"yaptırım",
"işçi hakları",
"limited şirket",
"sınırlı ayni hak",
"telif hakkı",
"unutulma hakkı",
"yolsuz tescil",
"zamanaşımı"
};
Я не знаю, как это сделать. Я думал написать цикл foreach, как показано ниже. Но я не знаю, что писать в цикле foreach.
var newList = new List<string>();
foreach (var l in list)
{
// WHAT MUST I DO IN HERE?
}
@Т.С. - Эти значения представлены в виде списка. Список также взят из базы данных. Так как я работал над списком, то не хотел беспокоить вас, мастера, базой данных. Что касается того, почему некоторые предметы... Я по профессии юрист. Программное обеспечение — это хобби, которое значительно облегчает мою работу. Таким образом, более юридически правильными являются те, которые я дал в словарном ключе.
Хранение дубликатов в виде строк, разделенных запятыми, в Dictionary<string, string>
не будет ни красивым, ни эффективным. Вместо того, чтобы представлять нам свою попытку решения проблемы и просить нас исправить ваше решение, предпочтительнее описать проблему как можно лучше и позволить нам предложить решение. Скорее всего, таким образом вы получите лучшую помощь.
Допустим, список содержит значения "anonim"
и "anonim şirketler"
и не содержит значения "anonim şirket"
. Что должно произойти в таком случае? Следует ли удалить одно из двух похожих значений или оба должны остаться в списке? Если один из них следует удалить, то какой?
@TheodorZoulias - Я ценю, что ты пытаешься мне помочь. Но список действительно похож на тот пример, который я привел. Итак, список содержит как anonim
, anonim şirket
и anonim şirketler
.
Кстати, не обижайтесь на предпочитаемый вами алфавит, но здесь больше шансов получить помощь, если ваш пример набора данных состоит из английских слов. Большинство людей здесь лучше знакомы с английским языком и латинским алфавитом, и им будет легче визуально отличить похожие строки от несходственных. Чем проще вы поможете нам вам помочь, тем больше вероятность, что вам помогут.
Если входные и выходные данные программы статичны, не пишите программу. Если входные данные могут измениться, вы сможете объяснить ожидаемое поведение для другого набора данных. Вопрос: с list
и dict
, что является динамическим вводом, что является статическими вспомогательными данными и/или промежуточными результатами (обработанными на основе ввода)?
Если список уже известен, рассматривали ли вы возможность его создания вручную и сохранения списка в какой-либо другой таблице базы данных? Это должно быть более просто и менее подвержено ошибкам, чем попытка программной дедупликации известного списка.
Для вас софт – хобби, для нас – серьезный бизнес. Вы должны помочь нам понять вашу проблему, ваш вклад, результаты и критерии. Даже ИИ не сможет решить ее без единого алгоритма. например, ИИ может найти на изображении с камеры белый квадрат и т. д. Ни один из ваших комментариев не помог нам приблизиться к предложению. Например, если у вас есть "anonim", "anonim şirket", "anonim şirketler"
, - как вы решаете, что оставить, а что продублировать и выбросить?
@TheodorZoulias Разве не было ясно, что если список содержит ключ в словаре, элементы в значении этого ключа следует удалить? Вот как я это понял, и что показывают ожидаемые результаты.
@Т.С. Он уточнил, что если ключ присутствует в списке, элементы связанного значения должны быть удалены из списка. Это очень простой алгоритм.
@RufusL да, это совершенно ясно. Это не настолько общая проблема, чтобы ее стоило решать, поскольку список уже известен. ОП не может указать, каким должен быть результат для немного другого ввода, что весьма разочаровывает. Лично я хотел бы попытаться решить более общую проблему, но не эту.
@RufusL «если список содержит ключ в словаре, элементы в значении этого ключа должны быть удалены» - я бы предложил включить это уточнение в вопрос (если вы на 100% уверены, что оно описывает алгоритм, который ОП хочет реализовать).
@TheodorZoulias Он включил это в вопрос: «Если ключ словаря существует в списке, я хочу игнорировать элементы, разделенные запятыми в значении словаря».
@RufusL ах, да, ты прав.
Простой способ сделать это (но не самый эффективный):
Мы можем разделить значение на запятую, чтобы создать мини-список для перебора для удаления элементов (обратите внимание, что было бы проще, если бы вместо этого вы использовали Dictionary<string, List<string>>
):
// Make a copy of the original list
var new_list = list.ToList();
// Loop through the dictionary
foreach (var item in dict)
{
// If our new list contains a key
if (new_list.Contains(item.Key))
{
// Loop through the values associated with
// that key and remove them from the list
foreach(var value in item.Value.Split(',').Select(i => i.Trim()))
{
new_list.Remove(value);
}
}
}
// Display results
Console.WriteLine(string.Join("\n", new_list));
Обновлено:
Более эффективным способом, вероятно, было бы сначала создать список элементов, которые нужно исключить, путем поиска ключей словаря в списке, как мы делали раньше, но собирая все значения в отдельный список, а затем мы можем использовать метод Except
для удалите элементы (что дает дополнительное преимущество [для некоторых] в одной строке):
var new_list = list.Except(dict
.Where(item => list.Contains(item.Key))
.SelectMany(item => item.Value.Split(',').Select(i => i.Trim())))
.ToList(); // Call ToList() if you need a List and not just an IEnumerable
Здесь у вас есть алгоритм O(n³). List<T>.Remove
— это O(n), и вы вызываете его во внутреннем цикле.
@TheodorZoulias Да, я сразу сказал, что это неэффективно. Просто даю отправную точку для размышлений об этом.
Руфус, текст в вашем ответе создает впечатление, что медленная часть - это «сделать копию исходного списка», а не то, что следует дальше.
Теперь все стало лучше, но все еще неясно, в чем причина низкой эффективности, и это необходимо улучшить, если выполнение алгоритма займет несколько часов.
@TheodorZoulias правда. я добавил более эффективный метод для этого, но думаю, что исходного ответа было достаточно для вопроса. взгляд на сам дизайн заставляет меня поверить, что это не наименее эффективный фрагмент кода. :)
Я скептически отношусь к тому, что подход LINQ является улучшением (в отношении производительности). Он не использует преимущества того, что dict
является словарем.
@TheodorZoulias, дайте мне знать, если придумаете что-нибудь получше!
Скорее всего, не буду. Я не считаю этот вопрос достаточно интригующим/сложным/интересным.
Здесь вам нужно лучше определить свое намерение. Например, почему
{"tapu senedi", "tapu, tapu kütüğü"}
, а не{"tapu", "tapu senedi"}
— оба у вас в первом списке. Откуда вы берете эти значения и т. д. Каков порог отклонения значения и т. д.?