Algorithm 设置值使用的逻辑

Algorithm 设置值使用的逻辑,algorithm,function,methods,foreach,Algorithm,Function,Methods,Foreach,我想实现一个逻辑“如果此_字段已初始化,则:获取其值,否则:使用所有列出对象中所有已初始化此_字段的平均值”。我知道我可以使用特定字段在Foreach循环中检查None,但我希望在所有字段上使用一个函数/接口/smth(有50多个字段,因此重载可能太长,太严格,以防我将向类中添加更多字段)。 例如: Foreach (City thiscity in Cities) { thiscity.PolutionRoughEstimation = thiscity.PolutionData.Me

我想实现一个逻辑“如果此_字段已初始化,则:获取其值,否则:使用所有列出对象中所有已初始化此_字段的平均值”。我知道我可以使用特定字段在Foreach循环中检查None,但我希望在所有字段上使用一个函数/接口/smth(有50多个字段,因此重载可能太长,太严格,以防我将向类中添加更多字段)。 例如:

Foreach (City thiscity in Cities) {
    thiscity.PolutionRoughEstimation = thiscity.PolutionData.MetalsPortion != None ?
    thiscity.PolutionData.MetalsInAirPortion : 
    AverageKnown(Cities, Object.PolutionData.MetalsPortion) ;
}            
然而,我不想写所有参数的AverageKnown重载。我也不想为每个字段编写相同的Foreach循环。当我没有数据的时候,我只是想让我的系统使用这个组的平均值。也许有办法写一次,但我就是想不出来。 请帮帮我。

在C#中,你可以这样做,只需使用
Average
方法。见此:

    static void Main(string[] args)
    {
        List<City> cities = new List<City>();
        cities.Add(new City { Polution = 1, OtherField = 1 });
        cities.Add(new City { Polution = 5, OtherField = 5 });
        cities.Add(new City { OtherField = 2 });

        double? ave = cities.Average(c => c.Polution);
    }

    public class City
    {
        public int? Polution;
        public int? OtherField;
    }
static void Main(字符串[]args)
{
列表城市=新列表();
添加(新城市{pollution=1,OtherField=1});
添加(新城市{pollution=5,OtherField=5});
添加(新城市{OtherField=2});
双平均值=城市平均值(c=>c污染);
}
公营城市
{
公共污染;
公共int?OtherField;
}
ave
的值是
3
而不是
2


因此,这取决于您的编程语言/lib的实现。

现在我知道了如何使用表达式来填充缺少的数据

using System.Reflection;
public void FillGapInData(ref List<City> cities) 
        {
            foreach (var city in cities)
            {
                Type t = city.GetType();
                PropertyInfo[] parameteres = t.GetProperties(); 
                foreach (var parameter in parameteres)
                {
                    if (((double?)parameter.GetValue(city)).Equals(null))
                    {
                        double? a = cities
                            .Average(c => (double?)parameter.GetValue(c));
                        parameter.SetValue(city, a);
                    }
                }
            }
        }
使用系统反射;
公共空白填充数据(参考列表城市)
{
foreach(城市中的var城市)
{
类型t=city.GetType();
PropertyInfo[]参数=t.GetProperties();
foreach(参数中的var参数)
{
if(((双精度?)参数.GetValue(city)).Equals(null))
{
双a=城市
.Average(c=>(double?)参数.GetValue(c));
参数设置值(城市,a);
}
}
}
}
更准确的版本,以确保不会破坏字符串属性,并使用-1作为“缺少数据”的显式标记:

使用系统反射;
公共空白填充数据(参考列表城市)
{
foreach(城市中的var城市)
{
类型t=city.GetType();
PropertyInfo[]参数=t.GetProperties();
foreach(参数中的var参数)
{
if(parameter.PropertyType==typeof(double?)//检查我们这里有一个数字
if(((double?)parameter.GetValue(city))==-1)|///检查-1保留标记
(((双?)参数.GetValue(city)).Equals(null)))
{
双a=城市
.其中(c=>((双精度?)(参数.GetValue(c))!=-1)
&&!((双精度?)(parameter.GetValue(c)).Equals(null))//我无法停止
.Average(c=>(double?)(parameter.GetValue(c));
参数设置值(城市,a);
}
}
}
}

这个问题看起来非常特定于语言,所以您应该指出您正在使用的编程语言。我打算使用cpp或c。但我刚刚开始项目,所以我可以切换到其他东西,比如Python,以防它有我需要的东西。哦,我忘了lambdas。非常感谢。我能用它来填补所有的空白,而不仅仅是污染吗?比如:
foreach a in cities:{foreach f in City.Fields:{//我应该写什么来代替这行呢?如果(a.f==None):{a.f=cities.Average(c=>c.f);}}}}
@Nick,我不这么认为。您需要使用
using System.Reflection;
public void FillGapInData(ref List<City> cities) 
{
    foreach (var city in cities)
    {
        Type t = city.GetType();
        PropertyInfo[] parameteres = t.GetProperties();
        foreach (var parameter in parameteres)
        {
            if (parameter.PropertyType == typeof(double?)) //check we have a number here
            if ((((double?)parameter.GetValue(city)) == -1) || //check for -1 reserved mark
                (((double?)parameter.GetValue(city)).Equals(null))) 
            {
                double? a = cities
                            .Where(c => ( ((double?)(parameter.GetValue(c)) != -1) 
                                     && !(((double?)(parameter.GetValue(c))).Equals(null)))) //I couldn't stop
                            .Average(c =>  (double?)(parameter.GetValue(c)));
                parameter.SetValue(city, a);
             }
         }
     }
}