Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基于另一个特性连接特性的值_C#_Arrays_String_List_Linq - Fatal编程技术网

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}";
}