Как проверить, существует ли элемент из одного листа в других листах и не плодить циклы?

Проверяю существует ли элемент одного листа в других листах, при этом наплодил кучу циклов. А как можно этого избежать?

 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 шт):

Автор решения: aepot

Ответ типа "Следите за руками"

Итерация 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 });
}

Всё, в рамках показанного кода и не изменяя условий хранения данных здесь вряд-ли что-то еще можно сделать.

→ Ссылка