比较/计数 System.Collections.ArrayList 中的值

发布于 2024-08-19 04:10:38 字数 315 浏览 8 评论 0原文

我正在清理 5 个文件以获得特定值。我预计不会有任何不同的值,但由于这是出于我自己的教育目的,我希望应用程序能够计算、比较和打印最流行的值。

例如:

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

我想要的结果是TOM,但作为新手,我真的不知道如何前进。

任何想法、建议或例子都将不胜感激。 谢谢。

I'm scrubbing 5 files for a specific value. I dont anticipate any different values, BUT since this is for my own educational purposes, I would like the application to count, compare and print the most popular value.

for example:

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

The result I would like is going to be TOM but being a novice, I really dont know how to move forward.

Any thoughts, suggestions or examples are greatly appreciated.
Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

多情出卖 2024-08-26 04:10:38

如果您可以使用 LINQ,则可以轻松地使用 LINQ 来完成此操作,使用类似于“

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

它将返回计数最高的值”或 default(Type) 的查询。如果计数相等,它将返回第一个计数最高的计数。您可以将该方法与泛型一起放入扩展中以供一般使用。

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();
    }
}

如果您需要计数最高的所有值,例如您的列表是“BOB”、“JOHN”、“JOHN”、“TOM”、“TOM”,我想您可以改用此版本为了返回 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;
    }

You can easily do this with LINQ if you can use it, with a query similar to

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

It will return the value with the highest count, or default(Type). In cases of equivalent counts, it will return the first one with he highest count. You can put that method in your extensions with generics for general usage.

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();
    }
}

If you need all values that have the highest count, like if your list was "BOB", "JOHN", "JOHN", "TOM", "TOM" I guess you could use this version instead in order to return both JOHN and 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;
    }
傲娇萝莉攻 2024-08-26 04:10:38

您没有指定您正在使用的 .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);

You didn't specify the version of .Net / C# you are using, so I'll treat this for each version of C#: v1, v2 and 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);
娇纵 2024-08-26 04:10:38

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

就像一个循环声明; item 指的是循环变量。

group item by item into itemGroup

这将根据每个item 的值将其放入一个组中。

orderby itemGroup.Count() descending, itemGroup.Key

这会对每个组进行计数并对它们进行排序,以使最常见的位于第一个。如果有两个组的计数相同,则选择较小的值。 (由于每个组都包含所有相同的值,因此关键是计数的项目。)

select itemGroup.Key

这表示对于每个组,我们只需要计数的项目。

return itemsOrderedByCount.FirstOrDefault();

这将获取有序列表中的第一项(计数最高的项)。如果原始序列为空,则返回 null。

用法:

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

Assert.AreEqual("TOM", GetMostFrequent(items));

This is the kind of task for which LINQ is well-suited.

First, let's define what we're doing:

  1. Group the items by value
  2. Count each group
  3. Return the item whose group has the highest count

This query implements the above:

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();
}

The implementation reads very much like the high-level description, a nice side-effect of the declarative syntax. Here is a quick explanation of each part:

from item in items

is like a loop declaration; item refers to the loop variable.

group item by item into itemGroup

This puts each item in a group based on its value.

orderby itemGroup.Count() descending, itemGroup.Key

This counts each group and sorts them such that the most frequent is first. If there are two groups with the same count, the lesser value is chosen. (As each group contains all the same values, the key is the counted item.)

select itemGroup.Key

This says that for each group, we just want the counted item.

return itemsOrderedByCount.FirstOrDefault();

This grabs the first item in the ordered list (the one with the highest count). If the original sequence is empty, null is returned.

Usage:

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

Assert.AreEqual("TOM", GetMostFrequent(items));
小伙你站住 2024-08-26 04:10:38

您可以使用字典 (.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");

You can use a Dictionary (.NET 2.0+) to hold the repeated count of each value:

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);

If you're using C# 3.0 (.NET 3.5 +) then use:

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");
平定天下 2024-08-26 04:10:38
    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);
    }
    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);
    }
羅雙樹 2024-08-26 04:10:38

要遍历循环,您可以使用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);
    }
}

To move through the loop, you can use a foreach:

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

And to count the values, you can use a Hashtable, which maps keys to values. The key can be a name, and the value can be how many times you've seen that name in the list.

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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文