c# - 将字符串整数与 C# 中的范围进行比较的最有效方法
问题描述
我有一个需要检查的整数范围,但我用于比较的字段是一个字符串。
此字符串中可能包含非整数值。应跳过具有非整数值的字符串。
范围只是另外两个整数。
如果字符串列表中有一万个数字,我想知道最快的方法是什么。我考虑过简单的 int.TryParse,然后在范围之间进行条件检查,但我想知道是否有更快的方法来做到这一点。
不寻求意见,热衷于查看基准数字。
下面是数据和范围最小值/最大值的示例。
int min = 1000;
int max = 4999;
List<string> orderNumbers = new List<string>
{
"4021",
"*1002",
"5000",
"4500"
};
解决方案
TryParse
会很好用
var results = orderNumbers
.Select(x => int.TryParse(x, out var i) ? i : (int?) null)
.Where(x => x >= min && x <= max)
.Cast<int>() // resolve the nullable;
注意:您可以轻松地使用.Select(x => x.Value)
它来创建完全相同的 IL
如果您经常这样做,那么理想情况下您的列表不会是 type string
。
或者只是使用一个foreach
循环
var results = new List<int>(orderNumbers.Count);
foreach (var item in orderNumbers)
if (int.TryParse(item, out var value) && value >= min && value <= max)
results.Add(value);
如果你觉得无聊,创建你自己的Iterator 扩展方法
public IEnumerable<int> GetRange(this IEnumerable<string> source, int min, int max)
{
foreach (var item in source)
if (int.TryParse(item, out var value) && value >= min && value <= max)
yield return value;
}
用法
var results = orderNumbers.GetRange(min,max);
如果您正在查看原始效率,并且您的有效数字始终只是没有文化差异的数字,例如 1000 的分隔符等。您可能会从自己的TryParse
方法中获得更好的性能,并且(可选)使用指针迭代字符或Span<T>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe bool MyTryParse(string source, int min, int max, out int value)
{
value = 0;
fixed (char* p = source)
{
for (var i = 0; i < source.Length; i++)
if (p[i] >= '0' && p[i] <= '9')
value = value * 10 + p[i] - '0';
else
return false;
}
return value >= min && value <= max;
}
推荐阅读
- graph - 在 Cassandra 中存储树/图结构
- javascript - `fabric.js` 中的神奇数字来自哪里?
- python - 将 str 转换为日期时间。时间
- python - 一组点上的速度剖面
- python - 如何将时间戳从数据框列转换为仅天数?
- reactjs - React 类组件:为什么它不会导致重新渲染?
- linux - 绑定包含安装在 docker 容器中的安装点的卷
- python - 我想使用 jinja2 格式 {{all.{{item}}}} 从 html 中的 sqlalchemy 表中获取数据,其中 item 是字符串的元素,all 是数据
- c++ - swscanf 无法读取整数值
- c# - 带有参数 Action 的测试方法
使用 Nunit 和最小起订量 c#