【问题标题】:How to quickly cut up and reassemble a C# List?如何快速切割和重组 C# 列表?
【发布时间】:2015-02-11 21:24:36
【问题描述】:

设置: 我有一个会话变量,它带有一个以管道分隔的 ID 列表。这些 ID 与我网站中的视图相关,并且与面包屑生成器相关。

Session["breadCrumb"] = "1001|1002|1003|1004";

如果我在对应于 1002 的视图上,我想从会话变量中删除该 id 之后的所有内容。

我想使用类似的东西:

var curView = "1002";

if (Session["breadCrumb"] != null) {
    var crumb = Session["breadCrumb"].ToString().Split('|').ToList();
    var viewExists = crumb.Any(c => c.Value == curView);

    if (viewExists) {
        //remove everything after that item in the array.
    }

}

但我对方法持开放态度。

【问题讨论】:

  • 为什么不在 curView 上拆分,然后在分隔符上拆分? (只取拆分结果的第 0 个元素)
  • @TetsujinnoOni:因为如果curView 只是"1" 会发生什么?
  • 我接受 OP 的示例作为上下文并足以识别可能的范围。毕竟,我的第一直觉是不要将整数列表存储为管道分隔列表......
  • @TetsujinnoOni:我也是。但是为什么要做出非强制性的假设呢?
  • 我对其他方法完全持开放态度。我必须承认我不确定如何在会话中存储/访问列表。

标签: c# arrays list


【解决方案1】:

您可以使用TakeWhile 只取回拆分列表中当前视图之前的项目。

var curView = "1002";
if (Session["breadCrumb"] != null) 
{
    var crumb = Session["breadCrumb"].ToString().Split('|').ToList();
    var viewExists = crumb.TakeWhile(c => c != curView).ToList();
    viewExists.Add(curView);
    string result = string.Join("|",viewExists);
}

虽然这种方法有效,但我认为之前的答案(现在被 Andrew Whitaker 先生错误地删除)也是正确的。使用 IndexOf 应该更快,更少的拆分、循环、连接字符串。我建议惠特克先生取消删除它的答案。

编辑
这是来自Mr.Whitaker的已删除答案。
我将在这里重新发布,因为我认为它的方法更简单并且应该提供更好的性能,因此未来的读者也可以看到这个选项。

var crumb = Session["breadCrumb"].ToString()
int index = crumb.IndexOf(curView);
if (index >= 0)
{
    Session["breadCrumb"] = crumb.Substring(0, index + curView.Length);
}

如果 Andrew 决定取消删除其答案,我将很高兴删除这部分。请告诉我。

【讨论】:

  • 在这种情况下,c.Value 只是我的伪编码。 :)
  • 天哪,Whitaker 先生的回答真的会非常快:没有 .Split('|) 和没有 .ToList() 真的会加快速度。不过,您的回答对于演示 .TakeWhile() 可以在哪里使用非常有用(至少我发现它很有用!)。
【解决方案2】:

您可以只将List<string> 存储在Session directly 中。这使您不必手动拆分/连接字符串。我知道这并不能直接回答这个问题,但我相信这是一个更好的解决方案。

var curView = "1002";

var crumb = Session["breadCrumb"] as List<string>;
if (crumb != null) {
    var viewExists = crumb.Any(c => c.Value == curView);

    if (viewExists) {
        // remove everything after that item in the array.            
    }
}

【讨论】:

  • 我真的很喜欢这种方法,但//remove everything after that item in the array 对我来说也是一个症结所在。如何从列表中删除 curView 之后的所有内容?
  • 实际上,我自己已经回答了这个子问题。我设置了一个新列表,并遍历现有列表,将新列表填充到并包括当前视图,此时我停止制作新列表,并将会话设置为等于该列表。
  • 使用将我的列表直接放入会话中的方法,并跳过整个“分隔字符串”的事情只是门票。我想出了将列表重建到当前项目,然后从那里继续。非常感谢!
【解决方案3】:

我几乎后悔了,但坦率地说,我只想使用正则表达式:

var result = Regex.Replace(input, "(?<=(\\||^)" + current + ")(?=\\||$).*", "");

这并不能直接告诉您当前视图是否存在于输入中,但即使在此特定实例中使用正则表达式也可以做到这一点,但存在另一个非常简单的测试:

var viewExists = result.Length != current.Length;

【讨论】:

  • 看来这里至少有一个人真的不喜欢正则表达式。我想知道为什么。
  • 我没有尝试过@Jon 的代码,但是 RegEx 出现在代码搜索之前。更难编写,但速度更快,即使使用更大的数据也能保持性能。
  • 我不确定为什么会有反对票。我喜欢这种方法,因为我是正则表达式的粉丝,但最后我最终还是在会话中使用了列表。实际上,我使用了一个元组列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-03
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多