【问题标题】:Sort and Match List Item排序和匹配列表项
【发布时间】:2015-12-03 20:53:11
【问题描述】:

我有以下列表,其中每个列表项都有 StartEnd 值。请注意每个列表项的End 值与下一个列表项的Start 值匹配。

tableItems.Add (new SettingsCellItem() {Start=1000, End=4000});
tableItems.Add (new SettingsCellItem() {Start=4000, End=6000});
tableItems.Add (new SettingsCellItem() {Start=6000, End=8000});
tableItems.Add (new SettingsCellItem() {Start=8000, End=11300});
tableItems.Add (new SettingsCellItem() {Start=11300,End=12000});

只允许用户更新Start 值,当用户输入新的Start 值时,列表应根据Start 值排序,然后再次显示。

假设用户将第二个列表项从 {Start=4000,End=6000} 更新为 {Start=140,End=6000}

List<SettingsCellItem> sortedList =tableItems.OrderBy(o=>o.Start).ToList();

我得到以下输出。如您所见,End 值不再与 Start 值匹配。

电流输出:

{Start=140,  End=6000}
{Start=1000, End=4000}
{Start=6000, End=8000}
{Start=8000, End=11300}
{Start=11300,End=12000}

我想知道我怎样才能获得以下信息:

期望的输出

{Start=140,  End=1000}
{Start=1000, End=6000}
{Start=6000, End=8000}
{Start=8000, End=11300}
{Start=11300,End=12000}

【问题讨论】:

  • 您用于获取“当前输出”的代码是什么?你不能只按“开始”属性排序吗?
  • 如果您知道哪个单元格已更新,那么您可以找到移动此单元格的位置,并在移动用户更新的单元格后更新上一个或/和下一个单元格。
  • sortedList 是我的当前输出
  • 如果单元格的开头是另一个单元格的结尾,是否应该新的用户条目修改其他单元格的开头和结尾以获得所需输出中的链模式?

标签: c# linq list


【解决方案1】:

按开始排序后更新结束?

for(int i = 0; i < sortedList.Count - 1; i++)
{
    sortedList[i].End = sortedList[i+1].Start
}

如果您不想在编辑最后一个元素时丢失 End 值,请查看@Kevin Wells 的答案

Select 的示例:

var normalizedList = sortedList.Select(
                              (e, i) => 
                                 new SettingsCellItem() 
                                 {
                                   Start = e.Start, 
                                   End = i < sortedList.Count - 1 
                                       ? sortedList[i+1].Start : e.End
                                 }).ToList()

【讨论】:

  • 这有一个我的答案解决的错误,即您的代码可能会丢失最终的 End 值。想想如果用户编辑了列表的最后一个元素会发生什么。
【解决方案2】:

想到的明显答案是循环遍历新列表并更新结束值以匹配下一项的开始值。可能是这样的

public void UpdateEndValues(List<TypeLogSettingsCellItem> list)
 {
    int highestEndValue = list.Max (x => x.End);

    for(int i = 0; i < list.Count -1; i++)
    {
        list[i].End = list[i+1].Start;
    }

    list.Last.End = (list.Last.Start > highestEndValue) ? list.Last.Start : highestEndValue;
}

请注意,我的代码与 pikciu 之前的答案之间的主要区别在于,我的代码保留了最终的 End 值,如果最后一个 CellItem 是用户编辑的,他/她将不会保留该值

更新: @texas 指出我对新开始值高于旧最高结束值的情况处理不当,因此我更新了代码示例以涵盖该情况

【讨论】:

  • 你的循环会为最后一个元素抛出异常:) 索引超出范围:) 修复它:P
  • 不,它不会,循环故意不遍历列表的最后一个元素,注意“i
  • 公平地说,我删除了我的评论,因为我对您所做的编辑有误。我很好,你不更新你的答案,但可能会记下它是有缺陷的,因为当答案是最高投票的答案时,并不是每个人都会检查 cmets。
  • Kevin,您的解决方案不包括一种情况,即用户在任何Start 值中键入最大值,该值甚至大于最后一个元素的End 值。如果用户输入最大值,那么最高的End 值应该与用户输入的值相同。
  • 好点,虽然你的编辑实际上是我所知道的错误逻辑,所以我更新了我的代码以涵盖这种情况。所以现在它要么将最后一个 End 值设置为最后一个 Start 值,要么将之前的最高 End 值设置为更高的值
猜你喜欢
  • 2016-05-10
  • 2016-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-25
  • 2013-01-16
相关资源
最近更新 更多