c# - 如何检查可变长度字符串以查看它们是否以数组中的任何内容开头

标签 c# php mysql arrays linq

如果问题令人困惑,我深表歉意,因为我不太确定如何表达这个概念。

目前,我正在做的事情是像 MySQL 语句一样,但是我正在将其迁移到 C# 中处理,并计划在直接处理数据后将记录插入数据库,而不是插入到数据库中。数据库并使用以下概念:

$db->exec('UPDATE `' . date('Y-m',time() - self::DAYS_TO_MERGE) . '` SET `Cost`=0, `Location`=\'Flat Rate World\' WHERE `Cost` IS NULL AND `Caller` IN (' . $FlatRateWO. ') AND SUBSTR(`Dialed`,1,7) IN (\'0114021\',\'0117095\');');
$db->exec('UPDATE `' . date('Y-m',time() - self::DAYS_TO_MERGE) . '` SET `Cost`=0, `Location`=\'Flat Rate World\' WHERE `Cost` IS NULL AND `Caller` IN (' . $FlatRateWO. ') AND SUBSTR(`Dialed`,1,6) IN (\'011420\',\'011420\',\'011852\',\'011353\',\'011353\',\'011972\',\'011972\',\'011379\',\'011379\',\'011351\',\'011351\',\'011886\');');
$db->exec('UPDATE `' . date('Y-m',time() - self::DAYS_TO_MERGE) . '` SET `Cost`=0, `Location`=\'Flat Rate World\' WHERE `Cost` IS NULL AND `Caller` IN (' . $FlatRateWO. ') AND SUBSTR(`Dialed`,1,5) IN (\'01154\',\'01154\',\'01161\',\'01161\',\'01143\',\'01143\',\'01132\',\'01132\',\'01186\',\'01186\',\'01145\',\'01145\',\'01133\',\'01133\',\'01149\',\'01149\',\'01130\',\'01130\',\'01136\',\'01136\',\'01131\',\'01131\',\'01147\',\'01148\',\'01148\',\'01182\',\'01182\',\'01165\',\'01165\',\'01134\',\'01134\',\'01141\',\'01141\',\'01146\',\'01146\',\'01166\',\'01166\',\'01144\');');
$db->exec('UPDATE `' . date('Y-m',time() - self::DAYS_TO_MERGE) . '` SET `Cost`=0, `Location`=\'Flat Rate World\' WHERE `Cost` IS NULL AND `Caller` IN (' . $FlatRateWO. ') AND SUBSTR(`Dialed`,1,4) IN (\'1787\');');

上面的 PHP 代码执行查询,并根据起始数字的长度按顺序执行,从最长的数字组开始。这意味着,0114021 的长度为 7 位数字,在处理 011420 的长度为 6 位数字之前进行处理。这是为了防止 0111234 设置的价格与 011123 不同的情况。

这个过程 100% 正常工作,但是速度非常慢(平均大约 0.63 秒/查询超过 100,000 条记录)。其实际值来自一个 CSV 文件,我必须对其进行预处理,然后插入数据库,因此,如果我可以在插入之前对记录进行上述处理和计算,我想这会节省大量时间。

以下是将上述数组转换为 C# 的结果:

World = new List<string>() { "0114021", "0117095", "011420", "011852", "011353", "011972", "011972", "011379", "011351", "011886", "01154", "01161", "01143", "01132", "01186", "01145", "01133", "01149", "01130", "01136", "01131", "01147", "01148", "01182", "01165", "01134", "01141", "01146", "01166", "01144", "01135", "1787" };

我想知道的是,如何才能有效地(尽可能)完成相同的任务,例如比较以下数字,看看它们是否以 World 中的任何内容开头,请记住,我希望首先返回最长的匹配项。

011353123456277 ... should match 011353  
011351334478399 ... should match 01135  
011326717788726 ... should match nothing -- not found.

刚刚尝试了以下代码,但没有成功:

    if ( World.All( s => "01197236718876321".Contains( s ) ) ) {
        MessageBox.Show( "found" );
    }

    if ( World.All( s => s.Contains("01197236718876321") ) ) {
        MessageBox.Show( "found" );
    }

使用此处找到的示例 > Using C# to check if string contains a string in string array

第一个例子是使用嵌套的foreach,我想避免使用嵌套循环。 Linq 示例看起来不错,但我相信问题与我想要做的相反。

<小时/>

以下代码似乎有效,但我不确定它是否尊重数组中项目的顺序。似乎是,但需要确认,因为我不知道如何“观察”Linq 的魔法内部发生了什么:

    string foundas = "";
    string number = "01197236718876321";

    if(World.Any( 
        b => {
            if(number.StartsWith(b)) {
                foundas = b;
                return true;
            } else {
                return false;
            }
        }
    ) ) {
        MessageBox.Show( foundas );
    }
<小时/>

旁白

我将对这个问题进行跟进,因为下一部分有点复杂,我会获取一组费率(大约 10,000),并且它们也按组的长度排序,但它们有一个我当前正在计算的“成本”字段。

最佳答案

我会使用 StartsWith 检查所有命中,然后简单地获取结果中最长的字符串(通过聚合)。可能有比聚合更简单的东西。

var hit = World.Where( s => source.StartsWith(s)).Aggregate(string.Empty, (max,cur)=> max.Length > cur.Length ? max :cur);

if(!string.IsNullOrEmpty(hit))
    MessageBox.Show( "found "); 

关于c# - 如何检查可变长度字符串以查看它们是否以数组中的任何内容开头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31244300/

相关文章:

c# - WPF Metro UI 图表 - 负值

php - 从表单将项目插入 MySQL 数据库

php - Mysql 事务未按预期工作

php - 无法从其他库读取 PHPExcel 写入的行

MySQL:按计算的步长间隔限制结果

php - 在 php 中从 mysql 在表行中创建链接(成员列表)

PHP 跳过函数调用输出

c# - 任务中的计时器未触发

c# - 如何构建自己的自定义代码片段?

c# Matrix of pictureBox 的