@mr_blond97

C# Как получить элементы из List используя Linq и Dictionary Class в запросе?

Модель:
public class Word
{
    public Dictionary<string, string> Langs { get; set; }
}


Список языков которые нужно использовать:
// I need to use these 2 langs only
    List<string> langsToUse = new List<string> { "en", "pl" };


Список слов содержит языки которые не нужно выбирать, а так содержит "" в значениях локализаций.
List<Word> wordsList = new List<Word> {
new Word {
    Langs = new Dictionary<string, string> {
        {"en", "Dog"},
        {"pl", "Pies"},
        {"ge", "Hund"},
        //... and so on
    }},
new Word {
    Langs = new Dictionary<string, string> {
        {"en", "Kat"},
        {"pl", ""},
        {"ge", ""}
        //... and so on
    }},
new Word {
    Langs = new Dictionary<string, string> {
        {"en", "Car"},
        {"pl", ""},
        {"ge", ""}
        //... and so on
    }},
};


Простой путь валидации:
// And value shouldn't be ""
var validWords = wordsList.Where(p => p.Langs["en"] != "" &&
                                      p.Langs["pl"] != "");


Но я не хочу каждый раз вручную прописывать "en", "pl", нужно это автомитизировать, например так:
// use foreach for validate words
List<Word> validWords_2 = new List<Word>();

foreach(Word word in wordsList)
{
    bool isWordValid = true;

    foreach(string lang in langsToUse)
    {
        if(word.Langs[lang] == ""){
            isWordValid = false;
        }
    }

    if(isWordValid) {
        validWords_2.Add(word);
    }
}


Как упростить этот вариант оптимизации и можно ли сделать это с использованием Dictionary в Linq запросе?
  • Вопрос задан
  • 4033 просмотра
Решения вопроса 1
В компиляторе не проверил, но должно работать. То, что вам нужно на последней строке.

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp
{
    class Program
    {
        public class Word
        {
            public Dictionary<string, string> Langs;
        }

        static void Main(string[] args)
        {
            List<string> langsToUse = new List<string> { "en", "pl" };

            List<Word> wordsList = new List<Word> {
                new Word {
                    Langs = new Dictionary<string, string> {
                        {"en", "Dog"},
                        {"pl", "Pies"},
                        {"ge", "Hund"},
                        //... and so on
                    }},
                new Word {
                    Langs = new Dictionary<string, string> {
                        {"en", "Kat"},
                        {"pl", ""},
                        {"ge", ""}
                        //... and so on
                    }},
                new Word {
                    Langs = new Dictionary<string, string> {
                        {"en", "Car"},
                        {"pl", ""},
                        {"ge", ""}
                        //... and so on
                    }},
            };

            // select all words with condition
            List<Word> validWords_2 = wordsList.Where(w => langsToUse.All(l => w.Langs[l] != "")).ToList();
        }
    }
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@ColdSpirit
Код:
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp
{
    class Program
    {
        public class Word
        {
            public Dictionary<string, string> Langs;
        }

        static void Main(string[] args)
        {
            List<string> langsToUse = new List<string> { "en", "pl" };

            List<Word> wordsList = new List<Word> {
                new Word {
                    Langs = new Dictionary<string, string> {
                        {"en", "Dog"},
                        {"pl", "Pies"},
                        {"ge", "Hund"},
                        //... and so on
                    }},
                new Word {
                    Langs = new Dictionary<string, string> {
                        {"en", "Kat"},
                        {"pl", ""},
                        {"ge", ""}
                        //... and so on
                    }},
                new Word {
                    Langs = new Dictionary<string, string> {
                        {"en", "Car"},
                        {"pl", ""},
                        {"ge", ""}
                        //... and so on
                    }},
            };

            // LETS START

            // select all words with condition
            var words = wordsList.Where(w => true);

            foreach (var word in words)
            {
                // select langs where langsToUse contains it
                var langs = word.Langs.Where(l => langsToUse.Contains(l.Key));
                // show in console
                Console.WriteLine("Langs in langsToUse:");
                langs.ToList().ForEach(l => Console.WriteLine("{0} -> {1}", l.Key, l.Value));

                // is all values in selection are not epty?
                bool isValid = langs.All(l => l.Value != "");
                // show in console
                Console.WriteLine("All not Empty, method one: {0}", isValid);

                // OR another method
                // is any value contains empty string?
                bool containsEmptyStr = langs.Any(l => l.Value == "");
                isValid = !containsEmptyStr;
                Console.WriteLine("All not Empty, method two: {0}", isValid);

                // add some formatting
                Console.WriteLine("\n");
            }

            // COMBINE

            var selected = wordsList.Where(
                word => word.Langs
                    .Where(lang => langsToUse.Contains(lang.Key))
                    .All(l => l.Value != ""));

            // show in console:
            Console.WriteLine("Combined method:");
            selected.ToList()
                .ForEach(w => w.Langs.ToList()
                    .ForEach(l => Console.WriteLine("{0} -> {1}", l.Key, l.Value)));

            Console.ReadKey();
        }
    }
}


Вывод:
Langs in langsToUse:
en -> Dog
pl -> Pies
All not Empty, method one: True
All not Empty, method two: True


Langs in langsToUse:
en -> Kat
pl ->
All not Empty, method one: False
All not Empty, method two: False


Langs in langsToUse:
en -> Car
pl ->
All not Empty, method one: False
All not Empty, method two: False


Combined method:
en -> Dog
pl -> Pies
ge -> Hund


Это конечно всё интересно, но код нечитаемый получается. Используйте лучше обычные циклы или раздельный вариант запросов.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы