C# 基于另一个特性连接特性的值
我有这门课C# 基于另一个特性连接特性的值,c#,arrays,string,list,linq,C#,Arrays,String,List,Linq,我有这门课 public enum SubStatus { active, inactive, unset} public class SubItem { public SubStatus Status { get; set; } public string Value { get; set; } } 类中的值可以如下所示 List<SubItem> list = new List<SubItem>() { new SubItem() { St
public enum SubStatus { active, inactive, unset}
public class SubItem
{
public SubStatus Status { get; set; }
public string Value { get; set; }
}
类中的值可以如下所示
List<SubItem> list = new List<SubItem>()
{
new SubItem() { Status = SubStatus.active, Value = "1" },
new SubItem() { Status = SubStatus.active, Value = "2" }, //active again, add "2" to the previous
new SubItem() { Status = SubStatus.inactive, Value = "1" },
new SubItem() { Status = SubStatus.active, Value = "2" },
new SubItem() { Status = SubStatus.unset, Value = "2" },
new SubItem() { Status = SubStatus.unset, Value = "1" }, //unset again, add "1" to the previous
new SubItem() { Status = SubStatus.unset, Value = "1" } //unset again, add "1" to the previous
};
List <SubItem> output = new List<SubItem>()
{
new SubItem() { Status = SubStatus.active, Value = "12" },
new SubItem() { Status = SubStatus.inactive, Value = "1" },
new SubItem() { Status = SubStatus.active, Value = "2" },
new SubItem() { Status = SubStatus.unset, Value = "211" }
};
到目前为止,我所尝试的方法确实有效,但不知何故,我认为这种方法是错误的,并且有更好的方法使用linq
List<SubItem> result = new List<SubItem>();
SubItem temp = list.FirstOrDefault();
if (temp != null)
{
foreach (SubItem item in list.Skip(1))
{
if (temp.Status == item.Status)
{
temp.Value += item.Value;
}
else if (temp.Status != item.Status)
{
result.Add(temp);
temp = item;
}
}
}
result.Add(temp);
列表结果=新列表();
子项temp=list.FirstOrDefault();
如果(温度!=null)
{
foreach(列表中的子项。跳过(1))
{
如果(临时状态==项目状态)
{
温度值+=物料值;
}
否则如果(临时状态!=项目状态)
{
结果。添加(温度);
温度=项目;
}
}
}
结果。添加(温度);
标准Linq不提供这样的分组,但我们可以手动实现:
您可以使用
聚合
,但在我看来,它并不比常规的foreach
好:
var result = list
.Aggregate(
(IEnumerable<SubItem>)Array.Empty<SubItem>(),
(result, item) =>
result.LastOrDefault()?.Status == item.Status
? result.SkipLast(1).Concat(new [] { new SubItem { Status = item.Status, Value = result.Last().Value + item.Value } })
: result.Concat(new [] { item })
)
.ToList();
您无法使用标准LINQ完成所有这些,但您可以从以下方面进行利用: 它按
状态
对相邻项进行分组,使用选择新的子项
,然后使用组合分组值
上述示例输出以下内容:
Status=active,Value=12
Status=inactive,Value=1
Status=active,Value=2
Status=unset,Value=211
注意:上面覆盖了子项的ToString()
方法:
public override string ToString()
{
return $"Status={Status},Value={Value}";
}
var result = list
.Aggregate(
(IEnumerable<SubItem>)Array.Empty<SubItem>(),
(result, item) =>
result.LastOrDefault()?.Status == item.Status
? result.SkipLast(1).Concat(new [] { new SubItem { Status = item.Status, Value = result.Last().Value + item.Value } })
: result.Concat(new [] { item })
)
.ToList();
var result2 = list
.Select((item, index) => list
.Take(index + 1)
.Reverse()
.TakeWhile(x => x.Status == item.Status)
.Select((x, i) => Tuple.Create(x, index - i))
.Reverse()
)
.GroupBy(x => x.Select(y => y.Item2).Min())
.Select(x => x.Last())
.Select(x => new SubItem
{
Status = x.First().Item1.Status,
Value = string.Join("", x.Select(y => y.Item1.Value))
})
.ToList();
var result = list
.GroupAdjacent(item => item.Status)
.Select(grp => new SubItem
{
Status = grp.Key,
Value = string.Concat(grp.Select(item => item.Value))
});
foreach (var item in result)
{
Console.WriteLine(item.ToString());
}
Status=active,Value=12
Status=inactive,Value=1
Status=active,Value=2
Status=unset,Value=211
public override string ToString()
{
return $"Status={Status},Value={Value}";
}