Как проверить, существует ли элемент из одного листа в других листах и не плодить циклы?
Проверяю существует ли элемент одного листа в других листах, при этом наплодил кучу циклов. А как можно этого избежать?
foreach (var token in tokens)
{
it++;
foreach(var item in LexemTypes.Keyword)
{
if (token == item)
{
list.Add(new TokensTable() { Id = it, Token = token, Type = "Ключевое слово" });
}
}
foreach (var item in LexemTypes.ArithmeticSign)
{
if (token == item)
{
list.Add(new TokensTable() { Id = it, Token = token, Type = "Арифметическая операция" });
}
}
foreach (var item in LexemTypes.LogicalSign)
{
if (token == item)
{
list.Add(new TokensTable() { Id = it, Token = token, Type = "Логическая операция" });
}
}
foreach (var item in LexemTypes.Separator)
{
if (token == item)
{
list.Add(new TokensTable() { Id = it, Token = token, Type = "Разделитель" });
}
}
}
Ответы (1 шт):
Ответ типа "Следите за руками"
Итерация 1
Можно внутренний if заменить на Linq Where
foreach (var token in tokens)
{
it++;
foreach (var item in LexemTypes.Keyword.Where(x => x == token))
{
list.Add(new TokensTable() { Id = it, Token = token, Type = "Ключевое слово" });
}
foreach (var item in LexemTypes.ArithmeticSign.Where(x => x == token))
{
list.Add(new TokensTable() { Id = it, Token = token, Type = "Арифметическая операция" });
}
foreach (var item in LexemTypes.LogicalSign.Where(x => x == token))
{
list.Add(new TokensTable() { Id = it, Token = token, Type = "Логическая операция" });
}
foreach (var item in LexemTypes.Separator.Where(x => x == token))
{
list.Add(new TokensTable() { Id = it, Token = token, Type = "Разделитель" });
}
}
Итерация 2
Но зачем foreach, если item никак не используется, да и добавление происходит только по конкретному условию, если коллекция содержит элемент. Допустим это List<T>, тогда можно использовать List.Contains:
foreach (var token in tokens)
{
it++;
if (LexemTypes.Keyword.Contains(token))
{
list.Add(new TokensTable() { Id = it, Token = token, Type = "Ключевое слово" });
}
else if (LexemTypes.ArithmeticSign.Contains(token))
{
list.Add(new TokensTable() { Id = it, Token = token, Type = "Арифметическая операция" });
}
else if (LexemTypes.LogicalSign.Contains(token))
{
list.Add(new TokensTable() { Id = it, Token = token, Type = "Логическая операция" });
}
else if (LexemTypes.Separator.Contains(token))
{
list.Add(new TokensTable() { Id = it, Token = token, Type = "Разделитель" });
}
}
И для улучшения производительности я добавил else. Токен же не может быть одновременно нескольких типов?
Итерация 3
DRY = Don't Repeat Yourself = Не повторяй себя. Добавлю переменную, храняющую тип и повыкидываю фигурные скобки, для красоты.
foreach (var token in tokens)
{
it++;
string type;
if (LexemTypes.Keyword.Contains(token))
type = "Ключевое слово";
else if (LexemTypes.ArithmeticSign.Contains(token))
type = "Арифметическая операция";
else if (LexemTypes.LogicalSign.Contains(token))
type = "Логическая операция";
else if (LexemTypes.Separator.Contains(token))
type = "Разделитель";
else
continue;
list.Add(new TokensTable() { Id = it, Token = token, Type = type });
}
Итерация 4
Ради развлечения записал if-ы в виде тернарных операторов, но можно было бы остановиться и на предыдущей итерации
foreach (var token in tokens)
{
it++;
string type = LexemTypes.Keyword.Contains(token) ? "Ключевое слово"
: LexemTypes.ArithmeticSign.Contains(token) ? "Арифметическая операция"
: LexemTypes.LogicalSign.Contains(token) ? "Логическая операция"
: LexemTypes.Separator.Contains(token) ? "Разделитель" : null;
if (type != null)
list.Add(new TokensTable() { Id = it, Token = token, Type = type });
}
Всё, в рамках показанного кода и не изменяя условий хранения данных здесь вряд-ли что-то еще можно сделать.