Я вычищаю 5 файлов для определенной стоимости. Я не ожидаю различных ценностей, НО так как это в моих собственных образовательных целях, я хотел бы заявление посчитать, сравнить и напечатать самую популярную стоимость.
например:
ArrayList arrName = new ArrayList();
arrName.Add("BOB")
arrName.Add("JOHN")
arrName.Add("TOM")
arrName.Add("TOM")
arrName.Add("TOM")
Результат, который я хотел бы, будет TOM, но быть новичком, я действительно не знаю, как продвинуться.
Любые мысли, предложения или примеры значительно ценятся.Спасибо.
Вы можете использовать словарь (.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");
Вы можете легко сделать это с 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;
}
Вы не указываете версию .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);
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);
}
Для перемещения по циклу можно использовать 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);
}
}
Это такая задача, для которой LINQ хорошо подходит.
Во-первых, давайте определим, что мы делаем:
, этот запрос реализует вышеупомянутое:
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));