Использование LINQ в массиве строк для повышения эффективности C#

У меня есть строка уравнения, и когда я делю ее по своему шаблону, я получаю следующий массив строк.

string[] equationList = {"code1","+","code2","-","code3"};

Затем из этого я создаю список, который содержит только коды.

List<string> codeList = {"code1","code2","code3"};

Затем существующий код перебирает codeList и извлекает значение каждого кода и заменяет значение в уравнении уравнения приведенным ниже кодом.

foreach (var code in codeList ){

 var codeVal = GetCodeValue(code);

  for (var i = 0; i < equationList.Length; i++){
     if (!equationList[i].Equals(code,StringComparison.InvariantCultureIgnoreCase)) continue;
                        equationList[i] = codeVal;
                        break;
     }
}

Я пытаюсь повысить эффективность и считаю, что могу избавиться от цикла for в foreach с помощью linq.

Мой вопрос: будет ли лучше, если я сделаю это с точки зрения ускорения процесса?

Если да, то можете ли вы помочь с оператором linq?

3 ответа

Прежде чем перейти к LINQ..., который не решает проблем, которые вы описали, давайте рассмотрим логику, которая у вас есть.

  1. Мы разбиваем строку с помощью "шаблона". Как?
  2. Затем мы создаем новый список кодов. Как?
  3. Затем мы перебираем эти коды и декодируем их. Как?
  4. Но так как мы забыли отслеживать, откуда появился этот код, мы теперь перебираем уравнение листинга (который представляет собой массив, а не List<T>) подставить результаты.

Кажется, немного запутанным для меня.

Может быть, более простое решение будет:

  1. Взять в string, и вернуться IEnumerable<string> слов (похоже на то, что вы делаете сейчас).
  2. Взять в IEnumerable<string> слов, и вернуть IEnumerable<?> ценностей.

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

//Ideally we return something more specific eg, IEnumerable<Tokens>
public IEnumerable<string> ParseEquation(IEnumerable<string> words)
{
    foreach (var word in words)
    {
        if (IsOperator(word)) yield return ToOperator(word);
        else if (IsCode(word)) yield return ToCode(word);
        else ...;
    }
}

Это очень похоже на оператор выбора LINQ... если бы я настоял, я бы предложил написать что-то вроде этого:

var tokens = equationList.Select(ToToken);
...
public Token ToToken(string word)
{
    if (IsOperator(word)) return ToOperator(word);
    else if (IsCode(word)) return ToCode(word);
    else ...;
}

Если GetCodeValue(код) этого еще не сделал, я полагаю, что он, возможно, мог бы использовать своего рода кеширование / словарь в своей реализации - хотя специфика диктует это.

Преимущества этого подхода в том, что он гибкий (мы можем легко добавить больше этапов обработки), простой для отслеживания (мы вводим эти значения и получаем их в результате, без изменения состояния) и легко пишется. Это также разбивает проблему на милые маленькие кусочки, которые решают свою собственную задачу, что очень поможет при попытках рефакторинга или при обнаружении проблем и проблем с производительностью.

Если ваш массив всегда чередующийся кодекс, то оператор этого LINQ должен делать то, что вы хотите:

    string[] equationList = { "code1", "+", "code2", "-", "code3" };
    var processedList = equationList.Select((s,j) => (j % 2 == 1) ? s :GetCodeValue(s)).ToArray();

Вам нужно будет проверить, быстрее ли это

Я думаю, что самым быстрым решением будет это:

var codeCache = new Dictionary<string, string>();
for (var i = equationList.Length - 1; i >= 0; --i)
{
    var item = equationList[i];
    if (! < item is valid >) // you know this because you created the codeList
        continue;

    string codeVal;
    if (!codeCache.TryGetValue(item, out codeVal))
    {
        codeVal = GetCodeValue(item);
        codeCache.Add(item, codeVal);
    }

    equationList[i] = codeVal;
}

Вам не нужен codeList, Если каждый код уникален, вы можете удалить codeCace,

Другие вопросы по тегам