C# 如何填补列表中属性值的空白?
我有一份清单:C# 如何填补列表中属性值的空白?,c#,linq,C#,Linq,我有一份清单: List<BtnCountViews> btnCountViewsList; 我有一个相当不寻常的要求,我不知道如何开始实施它 我想做的是在btnCountViewsList中填写'BtnCountViews,用于缺少的DayOfYear,对象的BtnCount为0,视图为0 首先,谁能告诉我如何在btnCountViewsList中找到一年中的最小和最大天数。注意,我用LINQ标记了它,但我不确定这是否是最好的工具 如果有人能建议一种方法来填充缺失的对象,我也会很
List<BtnCountViews> btnCountViewsList;
我有一个相当不寻常的要求,我不知道如何开始实施它
我想做的是在btnCountViewsList
中填写'BtnCountViews,用于缺少的DayOfYear,对象的BtnCount为0,视图为0
首先,谁能告诉我如何在btnCountViewsList
中找到一年中的最小和最大天数。注意,我用LINQ标记了它,但我不确定这是否是最好的工具
如果有人能建议一种方法来填充缺失的对象,我也会很高兴,但这并不是这个问题的重点,因为我想我需要先找出如何获得最小值和最大值 这正在linqpad上工作:
Int32 max = 0, min = 0;
btnCountViewsList.ForEach(x => {
min = Math.Min(x.Views, min);
max = Math.Max(x.Views, max);
});
这正在linqpad上工作:
Int32 max = 0, min = 0;
btnCountViewsList.ForEach(x => {
min = Math.Min(x.Views, min);
max = Math.Max(x.Views, max);
});
您可以添加缺少的天数,而不显式查找
min
和max
:
- 按
按升序对列表排序()DayOfYear
- 在列表的末尾开始一个循环索引
,然后按您的方式向后运行;当i
达到零时停止i
- 比较
和i
i-1的
属性DayOfYear
- 如果两天相差一天,则向下移动到下一个
i
- 否则,插入一条新记录,将
设置为DayOfYear
减一btnCountViewsList[i]
DayOfYear
的每个值的条目。下面是一个示例实现:
items.Sort((x, y) => x.DayOfYear.CompareTo(y.DayOfYear));
Console.WriteLine("Before: {0}", string.Join(", ", items.Select(x => x.DayOfYear)));
int i = items.Count-1;
while (i > 0) {
if (items[i].DayOfYear == items[i-1].DayOfYear+1) {
i--;
} else {
items.Insert(i, new BtnCountViews { DayOfYear = items[i].DayOfYear-1 });
}
}
您可以添加缺少的天数,而无需明确查找
min
和max
:
- 按
按升序对列表排序()DayOfYear
- 在列表的末尾开始一个循环索引
,然后按您的方式向后运行;当i
达到零时停止i
- 比较
和i
i-1的
属性DayOfYear
- 如果两天相差一天,则向下移动到下一个
i
- 否则,插入一条新记录,将
设置为DayOfYear
减一btnCountViewsList[i]
DayOfYear
的每个值的条目。下面是一个示例实现:
items.Sort((x, y) => x.DayOfYear.CompareTo(y.DayOfYear));
Console.WriteLine("Before: {0}", string.Join(", ", items.Select(x => x.DayOfYear)));
int i = items.Count-1;
while (i > 0) {
if (items[i].DayOfYear == items[i-1].DayOfYear+1) {
i--;
} else {
items.Insert(i, new BtnCountViews { DayOfYear = items[i].DayOfYear-1 });
}
}
我想做的是在BtnCountViews列表中填入'BtnCountViews,用于缺少的DayOfYear,其中包含BtnCount为0且视图为0的对象
我的建议是,我们不要试图寻找缺失的日子,我们要创造所有:
BtnCountViews[] arr = new BtnCountViews[365]; // or 366?
// suppose DayOfYear begins with 0.
for (int i = 0; i < arr.Length; i++)
{
arr[i] = new BtnCountViews { DayOfYear = i };
}
foreach (BtnCountViews item in btnCountViewsList)
{
arr[item.DayOfYear].BtnCount = item.BtnCount;
arr[item.DayOfYear].Views = item.Views;
}
我想做的是在BtnCountViews列表中填入'BtnCountViews,用于缺少的DayOfYear,其中包含BtnCount为0且视图为0的对象
我的建议是,我们不要试图寻找缺失的日子,我们要创造所有:
BtnCountViews[] arr = new BtnCountViews[365]; // or 366?
// suppose DayOfYear begins with 0.
for (int i = 0; i < arr.Length; i++)
{
arr[i] = new BtnCountViews { DayOfYear = i };
}
foreach (BtnCountViews item in btnCountViewsList)
{
arr[item.DayOfYear].BtnCount = item.BtnCount;
arr[item.DayOfYear].Views = item.Views;
}
试试下面的方法
btnCountViewsList = btnCountViewsList.Where(b => b.BtnCount == 0).Where(v => v.Views == 0).ToList();
如果我理解了您的要求,那么您希望得到BtnCount=0和Views=0的对象
这将选择Views=0的所有对象,然后IEnumarable将通过另一个LINQ表达式,在该表达式中它只选择另一个等于0的属性。请尝试以下操作
btnCountViewsList = btnCountViewsList.Where(b => b.BtnCount == 0).Where(v => v.Views == 0).ToList();
如果我理解了您的要求,那么您希望得到BtnCount=0和Views=0的对象
这将选择Views=0的所有对象,然后IEnumarable将通过另一个LINQ表达式,在该表达式中它只选择另一个等于0的属性。所以我的懒惰者说,制作一个回填列表,并将现有(和gappy)列表用作映射
public static IList<BtnCountViews> GetDefaultList()
{
var defaultList = Enumerable.Range(1, 365).Select(e =>
new BtnCountViews
{
DayOfYear = e,
BtnCount = 0,
Views = 0
}
).ToList();
return defaultList;
}
Dotnetfiddle的示例程序:
有没有更优雅的方法?毫无疑问。但这段代码大约在0.011秒内执行,对我来说,这是相当不错的,只要你不反复调用这个功能(例如,你决定分析30年的数据,需要在0.011秒内完成)。但是,我们必须更多地关注并行性,而不是代码的优雅性,以解决这一问题
希望这有助于…所以我的懒惰者说,制作一个回填列表,并将您现有的(和gappy)列表用作地图
public static IList<BtnCountViews> GetDefaultList()
{
var defaultList = Enumerable.Range(1, 365).Select(e =>
new BtnCountViews
{
DayOfYear = e,
BtnCount = 0,
Views = 0
}
).ToList();
return defaultList;
}
Dotnetfiddle的示例程序:
有没有更优雅的方法?毫无疑问。但这段代码大约在0.011秒内执行,对我来说,这是相当不错的,只要你不反复调用这个功能(例如,你决定分析30年的数据,需要在0.011秒内完成)。但是,我们必须更多地关注并行性,而不是代码的优雅性,以解决这一问题
希望这有助于…最短的linq方式,使用左外连接()和范围
var result = (from a in Enumerable.Range(0, 365)
join lst in btnCountViewsList on a equals lst.DayOfYear into ps
from p in ps.DefaultIfEmpty()
select (p==null) ? new BtnCountViews() { DayOfYear = a}:p).ToList()
最短的linq方式,使用左外连接()和范围
var result = (from a in Enumerable.Range(0, 365)
join lst in btnCountViewsList on a equals lst.DayOfYear into ps
from p in ps.DefaultIfEmpty()
select (p==null) ? new BtnCountViews() { DayOfYear = a}:p).ToList()
在其他一些回答中,如果没有硬编码,一年中的总天数将是366天
var range = new
{
Start = new DateTime(2017, 1, 1),
End = new DateTime(2017, 12, 31),
};
var days = Enumerable.Range(range.Start.DayOfYear, range.End.DayOfYear);
var query = from day in days
from counter in
(
from temp in btnCountViewsList
where temp.DayOfYear == day
select temp
).DefaultIfEmpty()
select new BtnCountViews
{
DayOfYear = day,
BtnCount = counter == null ? 0 : counter.BtnCount,
Views = counter == null ? 0 : counter.Views,
};
会给你类似的东西
在其他一些回答中,如果不硬编码,一年中的总天数将为366天
var range = new
{
Start = new DateTime(2017, 1, 1),
End = new DateTime(2017, 12, 31),
};
var days = Enumerable.Range(range.Start.DayOfYear, range.End.DayOfYear);
var query = from day in days
from counter in
(
from temp in btnCountViewsList
where temp.DayOfYear == day
select temp
).DefaultIfEmpty()
select new BtnCountViews
{
DayOfYear = day,
BtnCount = counter == null ? 0 : counter.BtnCount,
Views = counter == null ? 0 : counter.Views,
};
会给你类似的东西
使用
LINQ
,它有min和maxFinding的方法min和max只是一个开始-最终,OP想要做一些完全不同的事情。投票重新开放。@dasblinkenlight-谢谢。我不确定是应该问问题中的所有问题,还是先问一下如何填写日期,因为我认为这对我来说可能是一个太多的编程问题了。使用LINQ
,它有min和maxFinding的方法min和max只是一个开始-最终,OP想要做一些完全不同的事情。投票重新开放。@dasblinkenlight-谢谢。我不确定我是应该问问题中的所有问题,还是先问一下填写日期,因为我认为这可能是一个太多的编程问题,所以我不能这样问。谢谢你的建议。当你说“在列表的末尾开始一个循环索引i,然后