在csv文件的列中搜索值

时间:2013-04-09 15:41:05

标签: c# io

我有一个包含2列{c}个IDFlag的csv文件。有很多Flag值,但有一些表示不好的事情 - 错误,失败等。我需要做的是相当简单 - 搜索Flag列以查看是否有任何这些值在'Bad Flags'小组中。

我有以下代码可以执行我需要的操作 - 检查flags文件是否存在,遍历每一行,拆分它然后检查当前行是否有一个flag的元素然后检查该标志是否在我的错误中小组 - 如果我发现我完成了一件事:

private bool CheckFlagStatus( string directory )
{
    // Bad flags
    const int Flag1 = 1;
    const int Flag2 = 5; 
    const int Flag3 = 6;
    const int Flag4 = 42;
    const int Flag5 = 61;

    bool isGood = true;
    string flagFilePath= Path.Combine( directory, "flags.csv" );
    if ( File.Exists( flagFilePath) )
    {
        using ( StreamReader reader = new StreamReader( flagFilePath) )
        {
            string line;
            while ( !string.IsNullOrEmpty( line = reader.ReadLine() ) )
            {
                var splitval = line.Split(',');
                if ( splitval.Length == 2 )
                {
                    var flagString = splitval[1];
                    int flag;
                    bool parsed = Int32.TryParse( flagString, out flag );
                    if ( parsed )
                    {
                        if ( flag == Flag1 || flag == Flag2 || flag == Flag3
                            || flag == Flag4 || flag == Flag5 )
                        {
                            isGood = false;
                            break;
                        }
                    }
                }
            }
        }
    }
    return isGood;
}

虽然这有效,但这是一种非常线性的蛮力方法。虽然使用带有20行的flags.csv文件是完美的,但如果有一百万行会发生什么?我想知道如何使这更优雅或优化它有什么建议。

2 个答案:

答案 0 :(得分:1)

这已经过优化。如果有一百万行,则需要更长的时间,但性能是线性的,这比大多数算法要好得多。你可以让你的代码更优雅,但这只是造型的问题,与你实际做的事情或者它的最佳程度无关。请记住,优化的代码通常更长。

通过执行类似File.ReadLines的操作然后拆分新行然后拆分,然后循环遍历列表,只查看奇数索引,您的代码可能更优雅(更少的行)但性能不会更好。事实上,它可能会更糟。

答案 1 :(得分:1)

您的代码没问题,必须像检查每一行一样,我只是尝试使用LINQ和Readlines方法使代码更具可读性:

private bool CheckFlagStatus(string directory)
{
    badFlags = new[] { 1, 5, 6, 42, 61};
    string flagFilePath = Path.Combine(directory, "flags.csv" );

    if (File.Exists(flagFilePath))
    {
        var lines = File.ReadLines(flagFilePath)
                        .Where(line => !string.IsNullOrEmpty(line));

        foreach (var line in lines)
        {
            var splitval = line.Split(',');
            if (splitval.Length == 2)
            {
                var flagString = splitval.Last();
                int flag;

                if (int.TryParse(flagString, out flag))
                {
                    if (badFlags.Contains(flag)) return false;
                }
            }
        }    
    }
    return true;
}