Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从多个对象获取最大值、最小值和平均值的最快最简单方法_C#_List_Observablecollection - Fatal编程技术网

C# 从多个对象获取最大值、最小值和平均值的最快最简单方法

C# 从多个对象获取最大值、最小值和平均值的最快最简单方法,c#,list,observablecollection,C#,List,Observablecollection,我需要找到具有自己统计信息(ResultGroup类统计信息,基于所有结果统计信息)的对象列表的最大值、最小值和平均值(统计信息)。 当我添加对象时,值很容易更新,但是如果我更改或删除其中一个,那么我需要再次查找统计信息。通常会有超过40000个项目,我需要它是一个快速的操作 有没有比循环浏览所有项目更好的方法 public class ResultGroup { private Stats resultStats; //I need an updated stats p

我需要找到具有自己统计信息(ResultGroup类统计信息,基于所有结果统计信息)的对象列表的最大值、最小值和平均值(统计信息)。 当我添加对象时,值很容易更新,但是如果我更改或删除其中一个,那么我需要再次查找统计信息。通常会有超过40000个项目,我需要它是一个快速的操作

有没有比循环浏览所有项目更好的方法

public class ResultGroup
{
    private Stats resultStats;
    //I need an updated stats
    public Stats ResultStats
    {
        get { return resultStats; }
    }
    private readonly ObservableCollection<Result> results = new ObservableCollection<Result>();

    public ObservableCollection<Result> Results
    {
        get
        {
            return results;
        }
    }
    public ResultGroup()
    {
        this.resultStats = new Stats();
        this.results.CollectionChanged += new NotifyCollectionChangedEventHandler(CollectionChanged);
    }

    private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            //It works ok on add.
            Stats lastResultStat = this.results[this.results.Count - 1].Stat;
            if (resultStats.Max < lastResultStat.Max)
                resultStats.Max = lastResultStat.Max;

            if (resultStats.Min > lastResultStat.Min)
                resultStats.Min = lastResultStat.Min;

            resultStats.Mean = (resultStats.Mean * (this.results.Count - 1) + lastResultStat.Mean) / this.results.Count;
        }
        else if (e.Action == NotifyCollectionChangedAction.Reset)
        {
            this.resultStats = StatsFactory();
        }
        else if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            //Need to find the stats here
        }
        else if (e.Action == NotifyCollectionChangedAction.Replace)
        {
            //Need to find the stats here
        }
    }

    private Stats StatsFactory()
    {
        Stats dataStats = new Stats();
        dataStats.Max = float.MinValue;
        dataStats.Min = float.MaxValue;
        dataStats.Mean = 0;
        return dataStats;
    }
}

public class Result
{
    private float[] data;

    //Another class will fill data and set the Stats (max, min, mean)
    public float[] Data
    {
        get { return data; }
    }

    public Result(int lenght)
    {
        this.data = new float[lenght];
    }

    private Stats stat;
    public Stats Stat
    {
        get { return stat; }
        set { stat = value; }
    }
}

public class Stats
{
    public float Max { get; set; }
    public float Min { get; set; }
    public float Mean { get; set; }
}
公共类结果组
{
私人统计结果统计;
//我需要一个更新的数据
公共统计结果统计
{
获取{return resultStats;}
}
私有只读ObservableCollection结果=新ObservableCollection();
公众可观察的收集结果
{
得到
{
返回结果;
}
}
公共结果组()
{
this.resultStats=newstats();
this.results.CollectionChanged+=新的NotifyCollectionChangedEventHandler(CollectionChanged);
}
私有void CollectionChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{
if(e.Action==NotifyCollectionChangedAction.Add)
{
//它的工作正常添加。
Stats lastResultStat=this.results[this.results.Count-1].Stat;
if(resultStats.MaxlastResultStat.Min)
resultStats.Min=lastResultStat.Min;
resultStats.Mean=(resultStats.Mean*(this.results.Count-1)+lastResultStat.Mean)/this.results.Count;
}
else if(e.Action==NotifyCollectionChangedAction.Reset)
{
this.resultStats=StatsFactory();
}
else if(e.Action==NotifyCollectionChangedAction.Remove)
{
//需要在这里找到统计数据
}
else if(e.Action==NotifyCollectionChangedAction.Replace)
{
//需要在这里找到统计数据
}
}
私有统计数据StatsFactory()
{
统计数据状态=新统计数据();
dataStats.Max=float.MinValue;
dataStats.Min=float.MaxValue;
数据状态。平均值=0;
返回数据状态;
}
}
公开课成绩
{
私有数据;
//另一个类将填充数据并设置统计信息(最大值、最小值、平均值)
公共浮动[]数据
{
获取{返回数据;}
}
公开结果(整数长度)
{
this.data=新浮动[长度];
}
私人统计数据;
公共统计
{
获取{return stat;}
设置{stat=value;}
}
}
公共类统计
{
公共浮点最大值{get;set;}
公共浮点最小值{get;set;}
公共浮点平均值{get;set;}
}

您是否尝试在CollectionChanged内部使用LINQ运算符,如Min、Max和Average?

我认为您可以在首次初始化集合时缓存Max、Min值,然后可以将新值与缓存值进行比较


我可以建议下一个算法:如果我有一个巨大的值列表,我会将其按范围拆分,并为每个范围创建一个集合。对于每个集合,我都有一个缓存的平均值,当集合发生更改时,将重新计算该平均值。当我添加新值(或更改)时,我将看到元素的统计信息,并找到具有所需范围的集合。在这种情况下,我们得到一个stats作为附加索引,并且我们必须只在特定集合(第一个、最后一个)中找到max和min值。我们可以从所有集合的平均值中得到的平均值。我们也可以在第一个和最后一个集合中缓存最大值和最小值

您是否尝试使用DB进行此操作

因为DB有索引功能,这会有所帮助。还可以看看KDB或SAP的HANA,它具有基于垂直/列的数据库,可以在毫秒内穿透数百万行


也许像SqlLite这样简单的基于文件的数据库会有所帮助。(如果您正在处理大量数据,这也有助于减少内存使用)

删除项目时,只要在删除的项目等于当前最小值/最大值时循环所有项目即可


替换项目时,当删除的项目等于当前的最小值/最大值且新项目更大/更小时,您只需遍历所有项目。

//最好在集合中有一个具有所需属性的自定义集合,然后在集合顶部有linq来存储聚合值

 public class ObserCol: ObservableCollection<int>
{

    private int _maxValue = 0;

    public ObserCol() { 
        base.CollectionChanged +=new NotifyCollectionChangedEventHandler(CollectionChanged);
    }

    public int MaxValue{
        get {
            return _maxValue;
        }
    }

    private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            //Can use Linq to get the Max or Other Aggregate values..
        }
        else if (e.Action == NotifyCollectionChangedAction.Reset)
        {

        }
        else if (e.Action == NotifyCollectionChangedAction.Remove)
        {

        }
        else if (e.Action == NotifyCollectionChangedAction.Replace)
        {

        }
    }
}
公共类ObserCol:observeCollection
{
私有int_maxValue=0;
公共ObserCol(){
base.CollectionChanged+=新的NotifyCollectionChangedEventHandler(CollectionChanged);
}
公共整数最大值{
得到{
返回_maxValue;
}
}
私有void CollectionChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{
if(e.Action==NotifyCollectionChangedAction.Add)
{
//可以使用Linq获取最大值或其他聚合值。。
}
else if(e.Action==NotifyCollectionChangedAction.Reset)
{
}
else if(e.Action==NotifyCollectionChangedAction.Remove)
{
}
else if(e.Action==NotifyCollectionChangedAction.Replace)
{
}
}
}

查看,您希望查看
新项目
旧项目
属性,并根据添加或删除的内容重新计算。耶,太好了!我去看看。谢谢重新计算平均值,我想我可以使用旧的项目,但最大和最小值是不可能的。啊,是的。你能有效地做到这一点的唯一方法是某种排序的集合,它的开头是最小值,结尾是最大值。