Как получить список из двух JSON объектов

615
03 сентября 2017, 00:37

Здравствуйте, подскажите пожалуйста, у меня есть два JSON объекта

{  
   "1228":{  
      "price":836,
      "reference":"243107210-01",
      "idn":1228
   },
   "1294":{  
      "price":864,
      "reference":"243607210-01",
      "idn":1294
   }
}
{  
   "1228":[  
      {  
         "id_image":"35298",
         "legend":""
      },
      {  
         "id_image":"35299",
         "legend":""
      },
      {  
         "id_image":"35300",
         "legend":""
      }
   ],
   "1294":[  
      {  
         "id_image":"35298",
         "legend":""
      },
      {  
         "id_image":"35299",
         "legend":""
      },
      {  
         "id_image":"35300",
         "legend":""
      }
   ]
}

У них есть общее поле "1228" и "1294". В итоге хочу получить список объектов с полями, например: Id = 1228, Ref = 243107210-01, Image = 35298, 35299.

Вопрос в том как можно сделать выборку из двух JSON объектов в один результирующий список.

Answer 1

LINQ, хорошая вещь!

  • Берем ваши два JSON и загоняем в string (будь то чтение из файла, либо с сервера, не важно).
  • Далее определяем структуру каждого из них, в первом мы видим, что есть некий Dictionary, который содержит в виде ключа - int, а в виде значения определенную структуру данных, давайте это напишем: Dictionary<int, RootOne>

Сам RootOne - это класс, который определяет то, как будет выглядеть значение в нашем Dictionary:

public class RootOne
{
    public int Price { get; set; }
    public string Reference { get; set; }
    public int Idn { get; set; }
}
  • Отлично, со структурой первого JSON разобрались, что же со вторым? А с ним все тоже, но не совсем! Видно, что ключ нашего Dictionary аналогично первому имеет int, а вот значение тут уже некий список. Давайте напишем: Dictionary<int, List<RootTwo>>.

RootTwo в данном случае аналогично и с первым, структура каждого элемента в коллекции List:

public class RootTwo {
        [JsonProperty("id_image")]
        public int ImageId { get; set; }
        public string Legend { get; set; }
    } 

Замечу, что использовал для удобства JsonProperty, который указывает на название оригинального значения в JSON, что нам в итоге позволяет изменить само значение на более читаемое.

  • Хорошо, структура обоих JSON есть! Нужно загрузить сами данные. Я буду использовать удобную для этого библиотеку JSON.NET:
var jsonOne = JsonConvert.DeserializeObject<Dictionary<int, RootOne>>(jsonStrOne);// - Первый наш JSON, приведенный к Dictionary<int, RootOne>
var jsonTwo = JsonConvert.DeserializeObject<Dictionary<int, List<RootTwo>>>(jsonStrTwo);// - Второй JSON, приведенный к Dictionary<int, List<RootTwo>>
  • Отлично, теперь перейдем к LINQ и добавим немного "магии"!
var query = from listOne in jsonOne
    from listTwo in jsonTwo
    where listOne.Key == listTwo.Key
    select new {Id = listOne.Key, Ref = listOne.Value.Reference, Images = listTwo.Value};

В данном примере я взял две коллекции, которые получились у нас при загрузки JSON, далее условие where гласит, что будут выбраны элементы, которые совпадают из первого JSON во втором по ключу!. Затем с помощью select мы создаем новую коллекцию, которая будет содержать в себе "выжимку" из двух JSON сразу.

Осталось только вывести:

foreach (var item in query)
{
    Console.WriteLine($"Id: {item.Id}");
    Console.WriteLine($"Ref: {item.Ref}");
    Console.WriteLine($"Images: {string.Join(",", item.Images.Select(x=>x.ImageId))}");
    Console.WriteLine("----------------------------------");
}

Задачу можно по разному решить, к примеру можно не создавать новый объект, который будет объединять два JSON, а получать необходимые данные при проходе по первому циклом (тогда можно отказаться от созданного ранее query:

foreach (var one in jsonOne)
{
    var item = jsonTwo.FirstOrDefault(x => x.Key == one.Key);
    Console.WriteLine($"Id: {one.Key} ");
    Console.WriteLine($"Ref: {one.Value.Reference} ");
    Console.WriteLine($"Image: {string.Join(",", item.Value.Select(x=>x.ImageId))}");
    Console.WriteLine("----------------------------------");
}

В общем экспериментируйте! Выложил весь готовый код: тут. Удачи.

READ ALSO
listbox переместить выделение на последний элемент

listbox переместить выделение на последний элемент

Необходимо сделать пролистывание ListBox в самый низДелаю при инициализации окна:

345
Не работает стиль кнопки в ResourceDictionary

Не работает стиль кнопки в ResourceDictionary

Ребят, помогите решить задачкуЕсть ResourceDictionary (содержание см

340
Telegram.bot InlineKeyboardMarkup exception

Telegram.bot InlineKeyboardMarkup exception

Если два раза быстро нажать на кнопку созданую через InlineKeyboardMarkup, то вылетает ExceptionЕсли ожидать ответа, то все работает отлично

595