Сравните/подсчитайте ценности в Системе. Коллекции. ArrayList

Я вычищаю 5 файлов для определенной стоимости. Я не ожидаю различных ценностей, НО так как это в моих собственных образовательных целях, я хотел бы заявление посчитать, сравнить и напечатать самую популярную стоимость.

например:

ArrayList arrName = new ArrayList();
arrName.Add("BOB")
arrName.Add("JOHN")
arrName.Add("TOM")
arrName.Add("TOM")
arrName.Add("TOM")

Результат, который я хотел бы, будет TOM, но быть новичком, я действительно не знаю, как продвинуться.

Любые мысли, предложения или примеры значительно ценятся.Спасибо.

9
задан codekaizen 23 January 2010 в 19:48
поделиться

6 ответов

Вы можете использовать словарь (.NET 2.0+), чтобы удерживать повторное количество каждого значения :

Dictionary<string, int> counts = new Dictionary<string, int>();
foreach (string name in arrName) {
   int count;
   if (counts.TryGetValue(name, out count)) {
      counts[name] = count + 1;
   } else {
      counts.Add(name, 1);
   }
}

// and then look for the most popular value:

string mostPopular;
int max = 0;
foreach (string name in counts.Keys) {
   int count = counts[name];
   if (count > max) {
       mostPopular = name;
       max = count;
   }
}

// print it
Console.Write("Most popular value: {0}", mostPopular);

Если вы используете C # 3.0 (.NET 3.5 +), то используете:

var mostPopular = (from name in arrName.Cast<string>()
                   group name by name into g
                   orderby g.Count() descending
                   select g.Key).FirstOrDefault();

Console.Write("Most popular value: {0}", mostPopular ?? "None");
1
ответ дан 3 November 2019 в 01:56
поделиться

Вы можете легко сделать это с LINQ, если вы можете его использовать, с помощью запроса, аналогично

names.Distinct().OrderByDescending(s => names.Count(u => u == s))).FirstOrDefault();

, он вернет значение с наивысшим количеством, или по умолчанию (тип) . В случаях эквивалентных средств он вернет первый с самым высоким количеством. Вы можете поместить этот метод в вашим расширениям с помощью генеральных средств для общего использования.

class Program
{
    static void Main(string[] args)
    {

        IEnumerable<String> names = new String[] { "BOB", 
                                                   "JOHN", 
                                                   "TOM", 
                                                   "TOM", 
                                                   "TOM" };
        var res = names.Top(); //returns "TOM"
    }
}

public static class Extensions
{

    public static T Top<T>(this IEnumerable<T> values)
    {
        return values.Distinct().OrderByDescending(s => values.Count(u => u.Equals(s))).FirstOrDefault();
    }
}

Если вам нужны все значения, которые имеют наибольшее количество, как если бы ваш список «Боб», «Джон», «Джон», «Том», «Том» , я думаю, вы могли бы использовать это Версия вместо того, чтобы вернуть как John, так и TOM:

    public static IEnumerable<T> Top<T>(this IEnumerable<T> values)
    {
        List<T> ret = new List<T>();
        int max = -1;

        foreach (var val in values.Distinct())
        {
            int count = values.Count(t => t.Equals(val));

            if (count >= max)
            {
                if (count > max)
                {
                    ret.Clear();
                    max = count;
                }
                ret.Add(val); //stacks equivalent count, if applicable
            }
        }

        return ret;
    }
4
ответ дан 3 November 2019 в 01:56
поделиться

Вы не указываете версию .NET / C #, которые вы используете, поэтому я рассматриваю это для каждой версии C #: V1, V2 и V3.

C # V1:

class CountValueComparer : IComparer
{
    public int Compare(object x, object y)
    {
        DictionaryEntry left = (DictionaryEntry)x;
        DictionaryEntry right = (DictionaryEntry)y;

        return ((int)left.Value).CompareTo((int)right.Value);
    }
}

Hashtable counts = new Hashtable();

foreach(String value in arrName)
{
    if (counts.ContainsKey(value))
    {
        int valueCount = (int)counts[value];
        ++valueCount;
        counts[value] = valueCount;
    }
    else
    {
        counts[value] = 1;
    }
}

DictionaryEntry[] sorted = new DictionaryEntry[counts.Count];
counts.CopyTo(sorted, 0);
Array.Sort(sorted, new CountValueComparer());

foreach (DictionaryEntry entry in sorted)
{
    Console.Writeline("Name: {0}; Count: {1}", entry.Key, entry.Value);
}

C # V2:

class CountValueComparer : IComparer<KeyValuePair<String, int>>
{
    public int Compare(int x, int y)
    {
        return x.Value.CompareTo(y.Value);
    }
}

// if v2, use the List<T> class!
List<String> arrName = new List<String>();

arrName.Add("TOM");
// etc...

Dictionary<String, int> counts = new Dictionary<String, int>();

foreach(String value in arrName)
{
    int count;
    if (counts.TryGetValue(value, out count))
    {
        counts[value] = ++count;
    }
    else
    {
        counts[value] = 1;
    }
}

KeyValuePair<String, int>[] sorted = new KeyValuePair<String, int>[counts.Count];
counts.CopyTo(sorted, 0);
Array.Sort(sorted, new CountValueComparer());

C # V3:

// if v3, use the List<T> class!
var arrName = new List<String>();

arrName.Add("TOM");
// etc...

var counts = (from n in arrName 
              group n by n into g 
              select new { Name = g.Key, Count = g.Count() })
              .OrderByDescending(x => x.Count);
var top = counts.FirstOrDefault();
Console.WriteLine("Name: {0}; Count: {1}", top.Name, top.Count);
C # V3:

// if v3, use the List<T> class!
var arrName = new List<String>();

arrName.Add("TOM");
// etc...

var counts = (from n in arrName 
              group n by n into g 
              select new { Name = g.Key, Count = g.Count() })
              .OrderByDescending(x => x.Count);
var top = counts.FirstOrDefault();
Console.WriteLine("Name: {0}; Count: {1}", top.Name, top.Count);
2
ответ дан 3 November 2019 в 01:56
поделиться
    public static string GetMostPopular(ArrayList vals)
    {
        IDictionary<string, int> dict = new Dictionary<string, int>();
        int mx = 0;
        string ret = "";
        foreach (string x in vals)
        {
            if (!dict.ContainsKey(x))
            {
                dict[x] = 1;
            }
            else
            {
                dict[x]++;
            }
            if (dict[x] > mx)
            {
                mx = dict[x];
                ret = x;
            }
        }
        return ret;
    }

    static void Main()
    {
        ArrayList arrName = new ArrayList();
        arrName.Add("BOB");
        arrName.Add("JOHN");
        arrName.Add("TOM");
        arrName.Add("TOM");
        arrName.Add("TOM");
        string ans = GetMostPopular(arrName);
        Console.WriteLine(ans);
    }
1
ответ дан 3 November 2019 в 01:56
поделиться

Для перемещения по циклу можно использовать foreach:

foreach (string name in arrName) {
    Console.WriteLine(i);
}

А для подсчета значений можно использовать Hashtable, который сопоставляет ключи к значениям. Ключом может быть имя, а значение - сколько раз вы видели это имя в списке.

Hashtable nameHash = new Hashtable();
foreach (string name in arrName) {
    if (!nameHash.ContainsKey(name)) {
        nameHash.Add(name, 1);
    }
    else {
        int num = nameHash[name];
        nameHash.Add(name, num + 1);
    }
}
0
ответ дан 3 November 2019 в 01:56
поделиться

Это такая задача, для которой LINQ хорошо подходит.

Во-первых, давайте определим, что мы делаем:

  1. Группируйте элементы по значению
  2. Подсчет Каждая группа
  3. Вернуть товар, группа которого имеет наибольшее количество

, этот запрос реализует вышеупомянутое:

private string GetMostFrequent(IEnumerable<string> items)
{
    var itemsOrderedByCount =
        from item in items
        group item by item into itemGroup
        orderby itemGroup.Count() descending, itemGroup.Key
        select itemGroup.Key;

    return itemsOrderedByCount.FirstOrDefault();
}

Реализация очень похожа на описание высокого уровня, приятный побочный эффект декларативного синтаксиса. Вот быстрое объяснение каждой части:

from item in items

похоже на декларацию петли; Пункт относится к переменной петли.

group item by item into itemGroup

Это ставит каждый элемент в группе на основе его стоимости.

orderby itemGroup.Count() descending, itemGroup.Key

Это подсчитывает каждую группу и сортирует их так, что наиболее часто является первым. Если есть две группы с тем же количеством, выбрано меньшее значение. (Поскольку каждая группа содержит все те же значения, ключ - подсчитанный элемент.)

select itemGroup.Key

Это говорит о каждой группе, мы просто хотим подсчитанный товар.

return itemsOrderedByCount.FirstOrDefault();

Это захватывает первый элемент в упорядоченном списке (тот, который с наибольшим количеством). Если исходная последовательность пуста, нуль возвращается.

Использование:

var items = new[] { "BOB", "JOHN", "TOM", "TOM", "TOM" };

Assert.AreEqual("TOM", GetMostFrequent(items));
2
ответ дан 3 November 2019 в 01:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: