Подсчитывая количество 'если' отчетности в SAS


Я пишу на C# скрипт для подсчета 'если...то' Ведомости в 4000 строк код SAS. Я взял САС код как текстовый файл, а затем выполнить операцию. Вот мой код на C#:

class Program
{

static void Main(string[] args)
{

    List<String> list = new List<string>();
    list = File.ReadAllLines(@"C:\Users\Dey\Documents\Trucks\file.doc").ToList();
    int count = CountIfs(list);
    Console.ReadKey();
}

static int CountIfs(List<String> list)
{
    int count = 0;
    var index = new List<int>();
    var value = new List<String>();

    for (int i = 0; i < list.Count; i++)
    {
        if (list[i].Contains("if"))
        {
            if (list[i].Contains("then") || list[i + 1].Contains("then"))
            {
                count++;
                index.Add(i);
                String temp = null;

                if(list[i].Contains(";"))
                temp = list[i].Substring(0, list[i].IndexOf(";"));

                if (temp != null)
                {
                    value.Add(temp);
                }  
            }

        }
    }
    return count;
}
}

Я, по сути, проверка на "если" в каждой строке и если это нашли, я проверяю на "потом". И наконец, я также уверен, что одной строке кода, проверка на ";" . Моя логика заключается в том, что если все эти условия удовлетворяют, то я действительно способен извлечь все если-заявления от кода. В списке "значение" будет содержать все "если" заявления, содержащиеся в Кодексе. Сейчас у меня выход "значение" в текстовый файл в блокноте и перепроверили вручную около 20 записей. И до сих пор это, кажется, хорошо работает. Я надеялся, что кто-то может пруф-читайте мой код и скажите мне, если я могу улучшить его где-то возможно? Или эта логика достаточно точный?



167
0
c#
задан 15 февраля 2018 в 11:02 Источник Поделиться
Комментарии
2 ответа

Код в вопрос имеет некоторые недостатки, которые я здесь адрес:


  • var index = new List<int>(); не используются и должны быть удалены

  • var value = new List<String>(); не используются и должны быть удалены

  • Метод параметр List<String> list не используется в качестве List<T> а как массив, а следовательно, должен быть массивом.


Фиксация этих точек приводит к

private static int CountIfs(string[] linesOfCode)
{
var count = 0;

for (int i = 0; i < linesOfCode.Length; i++)
{
var line = linesOfCode[i];
if (line.Contains("if"))
{
if (line.Contains("then") || line[i + 1].Contains("then"))
{
count++;
}
}
}
return count;
}

Теперь код выглядит намного чище и меньше.



  • В if всегда быть первой инструкцией в строке кода после удаления ведущих пробелов и пробелы. Используя Contains() может привести к множеству ложных срабатываний. Предположим, что строка кода содержит следующий текст:
    "Я получил тесли-файл на этот счет от моего партнера, азатем."

  • А then всегда есть пробелы и есть пробелы или будет первая часть кода после удаления ведущих пробелов.

  • Как уже упоминалось в @папараци ответ вас могут возникнуть IndexOutOfRangeException заходя list[i + 1].

Позвольте представить новый метод, который просто обрабатывает проверьте if заявление.

private static bool HasIfStatement(string line)
{
return line.Trim().StartsWith("if ");
}

Нет, нам нужен способ, чтобы проверить then.

private static string[] spaceArray = new string[] { " " };
private static bool HasThenStatement(string line)
{
return line.Split(spaceArray , StringSplitOptions.RemoveEmptyEntries).Any(w => w == "then");
}

Ну этот метод какой-то быстрый и грязный, потому что он будет создавать много строк. Я оставлю это до вас, чтобы сделать его лучше.

Путем добавления флага в случае, если линия была if и не было then мы не можем получить IndexOutOfRangeException больше. Как побочный эффект мы могли теперь использовать foreach петли и IEnumerable<string> в качестве метода параметр типа.

Соединяем все вместе может выглядеть так

private static int CountIfs(IEnumerable<string> linesOfCode)
{
var count = 0;
var lastLineHadIf = false;
foreach (var line in linesOfCode)
{
if (lastLineHadIf)
{
lastLineHadIf = false;
if (HasThenStatement(line))
{
count++;
}
}
else if (HasIfStatement(line))
{
if (HasThenStatement(line))
{
count++;
}
else
{
lastLineHadIf = true;
}
}
}
return count;
}

private static bool HasIfStatement(string line)
{
return line.Trim().StartsWith("if ");
}

private static string[] spaceArray = new string[] { " " };
private static bool HasThenStatement(string line)
{
return line.Split(spaceArray , StringSplitOptions.RemoveEmptyEntries).Any(w => w == "then");
}

Я не знаю о регистра if и then так что вы можете изменить код, чтобы это учитывать.

Этот код не учесть замечания, так что вы должны настроить код для комментарии.

3
ответ дан 16 февраля 2018 в 07:02 Источник Поделиться

Вы можете получить индекс вне диапазона на этом

list[i + 1]

Почему вы используете строку, чтобы сохранить целое?

var value = new List<String>();

Могли бы просто сделать indexOf и искать >=0

0
ответ дан 15 февраля 2018 в 12:02 Источник Поделиться