Select 来自 IList 的行基于列值不为空 .net
Select rows from IList based on column value not null .net
我有一个几乎可以模拟以下内容的 IList table:
Code
Year
Type
Value
Active
Paid
ABC
2009
Lic
NULL
True
3.12
ABC
2009
Car
Audi
True
4.63
ABC
2010
Lic
Learner
True
5.41
ABC
2011
Lic
Full
True
7.82
ABC
2011
Car
Honda
True
5.19
ABC
2012
Lic
Expired
True
10.50
ABC
2013
Lic
NULL
True
15.71
XYZ
2009
Lic
NULL
True
4.63
XYZ
2010
Lic
Full
True
6.90
XYZ
2010
Car
Mazda
True
4.29
XYZ
2011
Lic
Full
True
9.73
XYZ
2011
Car
Mazda
True
9.17
每个代码会有多个类型,每个类型都有年度数据。单个代码的不同类型的年度数据量可能不同。
我将它作为变量 yv 引入方法中。
我有以下代码来获取数据的年份范围,但我想排除数据库中 Lic = NULL 和以下 returns 所有年份的那些。稍后我将使用有效的 (Lic != NULL) 年进行其他计算。
此外,关于如何存储有效年份的建议,以便可以通过其他方法访问它们,进行其他只需要有效年份数据的计算,我们也将不胜感激。我对此一窍不通。
public decimal RegoCosts(IList<YearlyValuesTable> yv)
{
IList<string> years = yv.Select(x => x.Year).Distinct().ToList();
// other magic not relevant to this question
return avePaidYearly;
}
谢谢
如果第一个问题我答对了,你想得到每个代码的年份范围,不计算值 == null 的行,例如“ABC”将有 2010-2011-2012,如果是这种情况,您可以尝试这样的操作:
public class listSetup()
{
public string CodeName { get; set; }
public List<int> Years { get; set; }
//put a empty contructor
}
然后
var newList = new List<ListSetup>();
newList.add(new ListSetup(){
CodeName = yv[0].Code,
Years = new List<int>()
});
for(int row = 0; row < yv.Count; row++)
{
if(newList.Last().CodeName != yv[row].Code)
{
//If code is changed distinct the Years in the code before
newList.Last().Years = newList.Last().Years.distinct().toList();
newList.add(new ListSetup(){
CodeName = yv[row].Code,
Years = new List<int>()
});
}
if(yv[row].Value != null)
{
newList.Last().Years.Add(yv[row].Year)
}
}
这应该给您留下一个列表,其中包含列表中每个代码的“代码名称”和一个不同的“年份”列表,也许这甚至可以帮助您解决第二个问题。
编辑:如果您只想从列表 yv 中删除 Value == null 的行,您可以像这样简化代码:
int LinesInYV = yv.Count;
for(int row = 0; row < LinesInYV; row++)
{
if(yv[row] != null)
{
if(yv[row].Value == null)
{
yv.RemoveAt(row);
}
}
else
{
break;
}
}
过滤掉
的所有条目
- 或者有
Type = "Lic"
和Value = null
,
- 或 包含
Code
和 Year
组合,匹配满足上述条件的条目,
您可以使用 .GroupBy()
按 Code
和 Year
对条目进行分组,然后使用谓词过滤每个 code 和 year 组@MakePeaceGreatAgain 在他们的评论中最初建议的过滤器表达式。
过滤后,您将得到 YearlyValuesTable
个对象的嵌套集合,使用 .SelectMany()
.
将其展平为 non-nested 集合
IList<YearlyValuesTable> validEntries = yv
.GroupBy(entry => ( entry.Code, entry.Year ))
.Where(entriesByCodeAndYear =>
entriesByCodeAndYear.All(entry => entry.Type != "Lic" || entry.Value != null))
.SelectMany(_ => _)
.ToList();
示例 fiddle here.
我有一个几乎可以模拟以下内容的 IList table:
Code | Year | Type | Value | Active | Paid |
---|---|---|---|---|---|
ABC | 2009 | Lic | NULL | True | 3.12 |
ABC | 2009 | Car | Audi | True | 4.63 |
ABC | 2010 | Lic | Learner | True | 5.41 |
ABC | 2011 | Lic | Full | True | 7.82 |
ABC | 2011 | Car | Honda | True | 5.19 |
ABC | 2012 | Lic | Expired | True | 10.50 |
ABC | 2013 | Lic | NULL | True | 15.71 |
XYZ | 2009 | Lic | NULL | True | 4.63 |
XYZ | 2010 | Lic | Full | True | 6.90 |
XYZ | 2010 | Car | Mazda | True | 4.29 |
XYZ | 2011 | Lic | Full | True | 9.73 |
XYZ | 2011 | Car | Mazda | True | 9.17 |
每个代码会有多个类型,每个类型都有年度数据。单个代码的不同类型的年度数据量可能不同。
我将它作为变量 yv 引入方法中。
我有以下代码来获取数据的年份范围,但我想排除数据库中 Lic = NULL 和以下 returns 所有年份的那些。稍后我将使用有效的 (Lic != NULL) 年进行其他计算。
此外,关于如何存储有效年份的建议,以便可以通过其他方法访问它们,进行其他只需要有效年份数据的计算,我们也将不胜感激。我对此一窍不通。
public decimal RegoCosts(IList<YearlyValuesTable> yv)
{
IList<string> years = yv.Select(x => x.Year).Distinct().ToList();
// other magic not relevant to this question
return avePaidYearly;
}
谢谢
如果第一个问题我答对了,你想得到每个代码的年份范围,不计算值 == null 的行,例如“ABC”将有 2010-2011-2012,如果是这种情况,您可以尝试这样的操作:
public class listSetup()
{
public string CodeName { get; set; }
public List<int> Years { get; set; }
//put a empty contructor
}
然后
var newList = new List<ListSetup>();
newList.add(new ListSetup(){
CodeName = yv[0].Code,
Years = new List<int>()
});
for(int row = 0; row < yv.Count; row++)
{
if(newList.Last().CodeName != yv[row].Code)
{
//If code is changed distinct the Years in the code before
newList.Last().Years = newList.Last().Years.distinct().toList();
newList.add(new ListSetup(){
CodeName = yv[row].Code,
Years = new List<int>()
});
}
if(yv[row].Value != null)
{
newList.Last().Years.Add(yv[row].Year)
}
}
这应该给您留下一个列表,其中包含列表中每个代码的“代码名称”和一个不同的“年份”列表,也许这甚至可以帮助您解决第二个问题。
编辑:如果您只想从列表 yv 中删除 Value == null 的行,您可以像这样简化代码:
int LinesInYV = yv.Count;
for(int row = 0; row < LinesInYV; row++)
{
if(yv[row] != null)
{
if(yv[row].Value == null)
{
yv.RemoveAt(row);
}
}
else
{
break;
}
}
过滤掉
的所有条目- 或者有
Type = "Lic"
和Value = null
, - 或 包含
Code
和Year
组合,匹配满足上述条件的条目,
您可以使用 .GroupBy()
按 Code
和 Year
对条目进行分组,然后使用谓词过滤每个 code 和 year 组@MakePeaceGreatAgain 在他们的评论中最初建议的过滤器表达式。
过滤后,您将得到 YearlyValuesTable
个对象的嵌套集合,使用 .SelectMany()
.
IList<YearlyValuesTable> validEntries = yv
.GroupBy(entry => ( entry.Code, entry.Year ))
.Where(entriesByCodeAndYear =>
entriesByCodeAndYear.All(entry => entry.Type != "Lic" || entry.Value != null))
.SelectMany(_ => _)
.ToList();
示例 fiddle here.