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