Среднее или максимальное количество строк - PullRequest
0 голосов
/ 07 марта 2012

Скажем, у меня были следующие значения

{ "Great", "Good", "Ok", "Poor", "Sucks" }

У меня был список вопросов с ответами на них.

Как бы я вычислил это с linq для объектов?Для целых чисел я бы сделал:

var q = (from g in questions select g.Answer).Max(); или select g.Answer).Avg();

Как бы я подошел к этому со строками, не целые числа ?

Ответы [ 7 ]

3 голосов
/ 07 марта 2012

Вы можете поместить свои «ответные» значения в словарь вместе с их значениями:

var answers = new Dictionary<string, int>();
answers.Add("Great", 5);
answers.Add("Good", 4);
answers.Add("Ok", 3);
answers.Add("Poor", 2);
answers.Add("Sucks", 1);

var q = questions.Select(q => answers[q.Answer]).Max();
2 голосов
/ 07 марта 2012

Можете ли вы сказать мне, "Великий"> "Отстой" или "Великий" <"Отстой"? </p>

Я думаю, что это зависит от независимого бизнеса. Если бы я был вами, я бы определил перечисление для управления им. как ниже

Enum Sample
{
   Great = 1, 
   Good, 
   Ok,
   Poor, 
   Sucks 
}

Тогда вы можете сравнить это в своем коде.

И, если вам просто нужно сравнить свой список по индексу, попробуйте этот способ.

        var data = new List<string>(){ "Great", "Good", "Ok", "Poor", "Sucks" };
        var result = data.Select((v, i) => new { Index = i, Value = v });

тогда вы можете дополнить его своей собственной логикой.

UPDATE

Вы можете попробовать этот способ, если вам просто нужно получить строку максимальной длины.

        var answers = new string[]{ "Grt", "Grt", "Good", "Poor" };
        var result = answers.Aggregate((a, b) => a.Length >= b.Length ? a : b);

Получить наиболее частое значение

        var answers = new string[]{ "Grt", "Grt", "Good", "Poor" };
        var result = answers.GroupBy(q => q)
                                .OrderByDescending(gp => gp.Count())
                                .Select(g => g.Key).FirstOrDefault();

Получить наиболее частое значение для нескольких значений

        var answers = new string[] { "Grt", "Grt", "Good", "Good","kk"};
        var results = from p in answers
                      group p by p into g
                      let max = answers.GroupBy(p => p).Select(p => p.Count()).Max()
                      where g.Count() == max
                      select g.Key;
1 голос
/ 07 марта 2012

Мое понимание вопроса (и последующего комментария) заключается в том, что в наборе ответов на вопросы вы хотите найти, какой ответ был наиболее распространенным.Попробуйте следующее:

class Question
{
    public string Answer;
}

static void Main(string[] args)
{
    var questions = new Question[] {
        new Question() { Answer = "Great" },
        new Question() { Answer = "Good" },
        new Question() { Answer = "Poor" },
        new Question() { Answer = "Good" },
        new Question() { Answer = "Great" },
        new Question() { Answer = "Sucks" }
    };
    var questionGroupsWithCount = from question in questions
                                  group question by question.Answer into questionGroup
                                  select new {
                                      QuestionCount = questionGroup.Count(),
                                      QuestionGroup = questionGroup
                                  };
    var mostCommonAnswerCount = questionGroupsWithCount.Max(item => item.QuestionCount);
    var mostCommonAnswers = from item in questionGroupsWithCount
                            where item.QuestionCount == mostCommonAnswerCount
                            select item.QuestionGroup.Key;

    foreach (var answer in mostCommonAnswers)
        Console.WriteLine("\"{0}\" was chosen {1:N0} time(s).", answer, mostCommonAnswerCount);
}

Вот что он делает:

  • Коллекция Question сгруппирована по идентичным Answer с.Число Question с в каждой из этих групп вычисляется и сохраняется в анонимном типе вместе с самой группой.
  • Размер самых больших групп извлекается.
  • * Keys, которые являются значениями полей Answer, групп с наибольшим размером.

Обратите внимание, что возможно иметь несколько ответов, которые являются "наиболее распространенными", и этоправильно справляется с этим.Вышеприведенный код печатает:

"Great" was chosen 2 time(s).
"Good" was chosen 2 time(s).
1 голос
/ 07 марта 2012
string[] answers = new[] { "Great", "Good", "Ok", "Poor", "Sucks" };

var coolestAnswer = answers[questions.Select(q => Array.IndexOf(answers, q.Answer)).Min()];
var averageAnswer = answers[(int)questions.Select(q => Array.IndexOf(answers, q.Answer)).Average()];
1 голос
/ 07 марта 2012
  var answerKinds = new[] { "Great", "Good", "Ok", "Poor", "Sucks" };
  var answerKindRanks = answerKinds.Select((kind, rank) => new { kind, rank })
   .ToDictionary(pair => pair.kind, pair => pair.rank);

  var questions = new[]
  {
    new{Q = "bla-bla", Answer = "Great"},
    new{Q = "bla-bla", Answer = "Sucks"},
    new{Q = "bla-bla", Answer = "Poor"},
  };
  var averageAnswer = answerKinds[(int)Math.Round(questions.Select(g => answerKindRanks[g.Answer]).Average())];
1 голос
/ 07 марта 2012

Создайте функцию (или просто словарь), которая отображает строковые значения в целые числа и использует запрос в вашем вопросе.Т.е. вызвать эту функцию с g.answer в качестве ввода.

0 голосов
/ 07 марта 2012

Я нашел ответ сам в другой теме.

string[] answers = { "Great", "Great", "Good", "Poor" };
string text = answers.AsQueryable().Select(x => x).
    OrderByDescending(x => x.Count()).FirstOrDefault();
...