C# 计算所有重复项,并确定字符串数组中每个重复项的平均时间

C# 计算所有重复项,并确定字符串数组中每个重复项的平均时间,c#,C#,我有一个数组,其中包含如下数据(字符串和时间数据用逗号分隔): 数组[0]=通道1,01:05:36 数组[1]=通道2,02:25:36 数组[2]=第1组,22:25:36 数组[3]=网络,41:40:09 数组[4]=LossOf,03:21:17 数组[5]=LossOf,01:13:28 数组[6]=通道1,04:25:36 阵列[7]=第二频道,00:25:36 。 . . 数组[xxx]=xxx,xxx 我想计算所有重复项,并确定发现的每个重复项的平均时间,如下所示: 项目1,通

我有一个数组,其中包含如下数据(字符串和时间数据用逗号分隔):

数组[0]=通道1,01:05:36

数组[1]=通道2,02:25:36

数组[2]=第1组,22:25:36

数组[3]=网络,41:40:09

数组[4]=LossOf,03:21:17

数组[5]=LossOf,01:13:28

数组[6]=通道1,04:25:36

阵列[7]=第二频道,00:25:36

。 . . 数组[xxx]=xxx,xxx

我想计算所有重复项,并确定发现的每个重复项的平均时间,如下所示:

项目1,通道1,2次,每次发生的平均时间约为xx分钟

第2项,频道2,2次出现,每次出现的平均时间约为xx分钟

第3项,损失,2次,每次发生的平均时间约为xx分钟

时间格式为hh:mm:ss

这是我到目前为止所做的,只给出了重复的总次数:

public void CountDuplicates(string[] myStringArray)
{
  //count duplicates
  ArrayList list = new ArrayList();
  int  loopCnt=0;

  foreach (string item in myStringArray)
  {
    if (!String.IsNullOrEmpty(myStringArray[loopCnt]) == true)
      list.Add(item);
    loopCnt++;
  }

  loopCnt = 0;
  Dictionary<string, int> distinctItems = new Dictionary<string, int>();
  foreach (string item in list)
  {
    if (!distinctItems.ContainsKey(item))
    {
      distinctItems.Add(item, 0);
      loopCnt++;
    }
    distinctItems[item] += 1;
  }
  foreach (KeyValuePair<string, int> distinctItem in distinctItems)
  {
    txtDisplayResults.AppendText("Alarm Error: " + distinctItem.Key + ",  How many times: " + distinctItem.Value + "\r\n");
  }
}
public void countreplicates(字符串[]myStringArray)
{
//重复计数
ArrayList=新建ArrayList();
int loopCnt=0;
foreach(myStringArray中的字符串项)
{
如果(!String.IsNullOrEmpty(myStringArray[loopCnt])==true)
列表。添加(项目);
loopCnt++;
}
loopCnt=0;
Dictionary DistrictItems=新字典();
foreach(列表中的字符串项)
{
如果(!区分项容器(项目))
{
添加(第0项);
loopCnt++;
}
区别项[项目]+=1;
}
foreach(KeyValuePair-Differentitem in-Differentitems)
{
txtDisplayResults.AppendText(“报警错误:+Differentitem.Key+”,次数:“+Differentitem.Value+”\r\n”);
}
}
可能是这样的:

保存您的值的通道类

class Channel
{
    public String Name { get; set; }
    public TimeSpan Duration { get; set; }
}
您的示例数据

var array = new[]{
    "Channel 1, 01:05:36",
    "Channel 2, 02:25:36",
    "Group 1, 22:25:36",
    "Network, 41:40:09",
    "Loss of, 03:21:17",
    "Loss of, 01:13:28",
    "Channel 1, 04:25:36",
    "Channel 2, 00:25:36",
};
询问

var channelGroups = array.Select(s =>
{
    var tokens = s.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
    var tsTokens = tokens[1].Split(':');
    return new Channel()
    {
        Name = tokens[0],
        Duration = new TimeSpan(
            int.Parse(tsTokens[0]),  // hours
            int.Parse(tsTokens[1]),  // minutes
            int.Parse(tsTokens[2]))  // seconds
    };
})
.GroupBy(c => c.Name)
.Select(g => new
{
    Channel = g.Key,
    Count = g.Count(),
    Average = g.Average(c => c.Duration.TotalMinutes)
});
输出:

foreach(var group in channelGroups)
{
   Console.WriteLine("Channel:[{0}] Count:[{1}] Average:[{2}]"
                    , group.Channel, group.Count, group.Average);
}
演示:


要我帮忙吗

var regex=new Regex(@"^(?<item>.*), (?<hours>\d{2}):(?<minutes>\d{2}):(?<seconds>\d{2})$");
var result=array.Select(a=> regex.Match(a)).Where(a=>a.Success)
           .Select (a => new { 
                               item=a.Groups["item"].Value,
                               time=decimal.Parse(a.Groups["hours"].Value)*60 + 
                                    decimal.Parse(a.Groups["minutes"].Value) +
                                    decimal.Parse(a.Groups["seconds"].Value)/60
                              })
           .GroupBy (a => a.item)
           .Select (a =>new {item=a.Key, duplicates=a.Count(),time=a.Average (b => b.time)} );
resultString
现在将成为您要查找的字符串

编辑——在请求使用字典之后,由于元组不可用,您需要定义一个类来保存临时数据。我已经使用了pulbic字段,但是您可以轻松地扩展到使用私有字段周围的属性

public class Data { 
   public int Occurrences;
   public decimal Time;

   public Data(int occurrences, decimal time) {
     this.Occurrences=occurrences;
     this.Time=time;
   }
}

var regex=new Regex(@"^(?<item>.*), (?<hours>\d{2}):(?<minutes>\d{2}):(?<seconds>\d{2})$");
var dict = new Dictionary<string,Data>();

foreach (var entry in array) {
    if (regex.IsMatch(entry)) {
      var match=regex.Match(entry);
      var item=match.Groups["item"].Value;
      var time=decimal.Parse(match.Groups["hours"].Value)*60 + 
                                        decimal.Parse(match.Groups["minutes"].Value) +
                                        decimal.Parse(match.Groups["seconds"].Value)/60;
      if (dict.ContainsKey(item)) {
        dict[item].Occurrences++;
                dict[item].Time+=time);
      } else {
        dict[item]=new Data(1,time);
      }
    }
}

StringBuilder sb=new StringBuilder();
foreach (var key in dict.Keys) {
    sb.AppendFormat("Item: {0}, # of occurences: {1}, Average Time: {2:0.00}\r\n", key, dict[key].Occurrences, dict[key].Time / dict[key].Occurrences);
}
var resultString=sb.ToString();
公共类数据{
公共事件;
公共十进制时间;
公共数据(整数次、十进制时间){
这个。事件=事件;
这个。时间=时间;
}
}
var regex=new regex(@“^(?.*),(?\d{2}):(?\d{2}):(?\d{2})$”;
var dict=新字典();
foreach(数组中的var条目){
if(regex.IsMatch(条目)){
var match=regex.match(条目);
var item=match.Groups[“item”].Value;
var time=decimal.Parse(match.Groups[“hours”].Value)*60+
decimal.Parse(match.Groups[“minutes”].Value)+
decimal.Parse(match.Groups[“seconds”].Value)/60;
if(dict.ContainsKey(项目)){
dict[item].事件++;
dict[项目]。时间+=时间);
}否则{
dict[项目]=新数据(1,时间);
}
}
}
StringBuilder sb=新的StringBuilder();
foreach(dict.Keys中的var键){
sb.AppendFormat(“项:{0},#发生次数:{1},平均时间:{2:0.00}\r\n”,键,dict[key]。发生次数,dict[key]。时间/dict[key]。发生次数);
}
var resultString=sb.ToString();

您尝试过什么?什么部分给您带来了问题(这不是代码编写服务,这是一个问答网站:)?您添加了一条关于某些数据的注释,这些数据具有无效的时间值(即仅注释)。您能否确认这种情况下的行为需要是什么?请详细解释您希望执行的操作,您尝试过的内容以及哪些内容有效或无效。
Timespan.ParseExact
将在
41:40:09
上浪费时间。0需要几个小时-23@BobVale:更正,必须使用构造函数和丑陋的
字符串。拆分
以初始化
时间跨度
。感谢Tim的帮助和非常完整的示例,它每次都提供正确的结果。你好,Bob,我如何使用txtDisplayResults.AppendText(“项:+a.Key+”,出现次数:+a.Count+”,平均时间:+a.Average+”\r\n)显示这些值;谢谢。更新的答案,而不是
{2:0.00}
简单地将时间设置为小数点后两位,如果你想要的话,可以使用不同的小数点格式。Bob和Tim,我已经尝试了这两种方法,它们都很有效!当数组上的数据不是时间格式而是字符串时,我将如何处理这种情况:数组[0]=通道1,01:05:36数组[1]=通道2,02:25:36数组[2]=组1,abc这两种方法都会给我一个错误,因为它们预期的是时间格式字符串(“:”)。请您建议修改代码,以处理时间格式和字符串(如“abc”)的混合。再次感谢,frnfrn您希望行为是什么?Bob,可以吗?我将在执行上述代码之前进行过滤。使用“Dictionary”创建类似于上述的解决方案是否涉及太多?再次感谢。frn
var resultString=result.Aggregate(new StringBuilder(),(sb,a)=>sb.AppendFormat("Item: {0}, # of occurences: {1}, Average Time: {2:0.00}\r\n",a.item,a.duplicates,a.time)).ToString();
public class Data { 
   public int Occurrences;
   public decimal Time;

   public Data(int occurrences, decimal time) {
     this.Occurrences=occurrences;
     this.Time=time;
   }
}

var regex=new Regex(@"^(?<item>.*), (?<hours>\d{2}):(?<minutes>\d{2}):(?<seconds>\d{2})$");
var dict = new Dictionary<string,Data>();

foreach (var entry in array) {
    if (regex.IsMatch(entry)) {
      var match=regex.Match(entry);
      var item=match.Groups["item"].Value;
      var time=decimal.Parse(match.Groups["hours"].Value)*60 + 
                                        decimal.Parse(match.Groups["minutes"].Value) +
                                        decimal.Parse(match.Groups["seconds"].Value)/60;
      if (dict.ContainsKey(item)) {
        dict[item].Occurrences++;
                dict[item].Time+=time);
      } else {
        dict[item]=new Data(1,time);
      }
    }
}

StringBuilder sb=new StringBuilder();
foreach (var key in dict.Keys) {
    sb.AppendFormat("Item: {0}, # of occurences: {1}, Average Time: {2:0.00}\r\n", key, dict[key].Occurrences, dict[key].Time / dict[key].Occurrences);
}
var resultString=sb.ToString();