C # - Преобразовать строку пары значений ключа, разделенных '=', в словарь - PullRequest
0 голосов
/ 03 июля 2018

Я извлекаю данные из API, который дает мне некоторую информацию в формате JSON. Однако одно из значений дает мне:

{X0=80,X1=80,X2=80,X3=80,X4=80,X5=80,X6=80,X7=80,X8=80,X9=80,X10=80,X11=80,X12=80,X13=80,X14=80,X15=80,X16=80,X17=80,X18=80,X19=80,X20=80,X21=80,X22=80,X23=80,X24=80,X25=80,X26=80,X27=80,X28=80,X29=80,X30=80,X31=80,X32=80,X33=80,X34=80,X35=80,X36=80,X37=80,X38=80,X39=80,X40=80,X41=80,X42=80,X43=80,X44=80,X45=80,X46=80,X47=80,X48=80,X49=80,X50=80,X51=80,X52=80,X53=80,X54=80,X55=80,X56=80,X57=80,X58=80,X59=80,X60=80,X61=80,X62=80}

Я пытаюсь декодировать это для использования в консольном приложении C # (.NET). Мой главный вопрос: как лучше всего извлечь эту строку в словарь или массив? Я не уверен, правильно ли я сформулировал это, поэтому, пожалуйста, поправьте меня, если я ошибаюсь!

Спасибо!

Ответы [ 3 ]

0 голосов
/ 03 июля 2018

Это можно сделать с помощью Regex Следующий шаблон будет захватывать ключи и значения в 2 отдельные группы (?<key>[^,]+)=(?<value>[^,]+)

Демо

Получив MatchCollection, выполните цикл foreach и добавьте каждый элемент в словарь.

0 голосов
/ 03 июля 2018
Var myAwesomeDictionary = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string,string>>(_yourJsonStringHere);
0 голосов
/ 03 июля 2018

Вы можете использовать Linq с Trim, Split, Select, ToDictionary

var result = json.Trim('{', '}')
                 .Split(',')
                 .Select(x => x.Split('='))
                 .ToDictionary(x => x[0], x => int.Parse(x[1]));

Console.WriteLine(string.Join("\r\n", result.Select(x => x.Key + " : " + x.Value)));

Полная демонстрация здесь

И только потому, что мне скучно

Тесты

Mode             : Release (64Bit)
Test Framework   : .NET Framework 4.7.1

Operating System : Microsoft Windows 10 Pro
Version          : 10.0.17134

CPU Name         : Intel(R) Core(TM) i7-3770K CPU @ 3.50GHz
Description      : Intel64 Family 6 Model 58 Stepping 9

Cores (Threads)  : 4 (8)      : Architecture  : x64
Clock Speed      : 3901 MHz   : Bus Speed     : 100 MHz
L2Cache          : 1 MB       : L3Cache       : 8 MB

Benchmarks Runs : Inputs (1) * Scales (3) * Benchmarks (3) * Runs (100) = 900

Результаты

--- Random Set ----------------------------------------------------------------------
| Value       |   Average |   Fastest |      Cycles |    Garbage | Test |      Gain |
--- Scale 100 -------------------------------------------------------- Time 0.229 ---
| Split       |  0.058 ms |  0.043 ms |     207,064 |  48.000 KB | Base |    0.00 % |
| JsonReplace |  0.077 ms |  0.064 ms |     273,556 |  24.000 KB | Pass |  -32.38 % |
| Regex       |  0.270 ms |  0.235 ms |     950,504 |  80.000 KB | Pass | -364.87 % |
--- Scale 1,000 ------------------------------------------------------ Time 0.633 ---
| Split       |  0.490 ms |  0.446 ms |   1,718,180 | 495.102 KB | Base |    0.00 % |
| JsonReplace |  0.671 ms |  0.596 ms |   2,352,043 | 195.078 KB | Pass |  -36.86 % |
| Regex       |  2.544 ms |  2.293 ms |   8,897,994 | 731.125 KB | Pass | -419.00 % |
--- Scale 10,000 ----------------------------------------------------- Time 5.005 ---
| Split       |  5.247 ms |  4.673 ms |  18,363,748 |   4.843 MB | Base |    0.00 % |
| JsonReplace |  6.782 ms |  5.488 ms |  23,721,593 |   1.829 MB | Pass |  -29.25 % |
| Regex       | 31.840 ms | 27.008 ms | 111,277,134 |   6.637 MB | Pass | -506.80 % |
-------------------------------------------------------------------------------------

Данные

private string GenerateData(int scale)
{
   var ary = Enumerable.Range(0, scale)
                       .Select(x => $"X{x}={Rand.Next()}")
                       .ToList();

   return $"{{{string.Join(",", ary)}}}";
}

Split

public class Split : Benchmark<string, Dictionary<string,int>>
{
   protected override Dictionary<string,int> InternalRun()
   {
      return Input.Trim('{', '}')
                       .Split(',')
                       .Select(x => x.Split('='))
                       .ToDictionary(x => x[0], x => int.Parse(x[1]));
   }
}

Regex

Зачислено на emsimpson92 с использованием Cast

public class Regex : Benchmark<string, Dictionary<string,int>>
{
   protected override Dictionary<string,int> InternalRun()
   {
      var regex = new System.Text.RegularExpressions.Regex("(?<key>[^,]+)=(?<value>[^,]+)");
      var matchCollection = regex.Matches(Input.Trim('{', '}'));
      return matchCollection.Cast<Match>()
                     .ToDictionary(
                         x => x.Groups["key"].Value,
                         x => int.Parse(x.Groups["value"].Value));
   }
}

JsonReplace

Зачислено на Hanzalah Adalan Изменено для работы с string.replace

public unsafe class JsonReplace : Benchmark<string, Dictionary<string,int>>
{
   protected override Dictionary<string,int> InternalRun()
   {
     return JsonConvert.DeserializeObject<Dictionary<string,int>>(Input.Replace("=", ":"));
   }
}

Дополнительные ресурсы

Метод String.Trim

Возвращает новую строку, в которой все начальные и конечные вхождения набор указанных символов из текущего объекта String удален.

Метод String.Split (String [], StringSplitOptions)

Разбивает строку на подстроки на основе строк в массиве. Вы можно указать, включают ли подстроки пустые элементы массива.

Enumerable.Select Method (IEnumerable, Func)

Проецирует каждый элемент последовательности в новую форму.

Метод Enumerable.ToDictionary (IEnumerable, Func)

Создает словарь из IEnumerable согласно указанная функция ключевого селектора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...