Обработка JSON

Moonwalker

Client
Регистрация
16.03.2016
Сообщения
1 674
Благодарностей
1 266
Баллы
113
Всем привет. Решили тут потестить работу с OZON, выгружаю оттуда данные по заказам, чтобы не сидеть в постоянно лагающем ЛК.
Допустим, получаю массив данных в JSON такого вида:
C#:
{"result":[
    {
    "order_id":111111,
    "status":"cancelled",
    "products":[
        {
        "sku":345345345,
        "quantity":1,
        "price":"300.0000",
        },
        {
        "sku":12312313,
        "quantity":2,
        "price":"300.0000",
        }
        ],
    },
    {
    "order_id":222222,
    "status":"delivering",
    "products":[
        {
        "sku":768678678,
        "quantity":1,
        "price":"1300.0000",
        },
        {
        "sku":456456456,
        "quantity":1,
        "price":"3200.0000",
        }
        ],
    }
]
}
Данных, понятно, больше, просто сократил до нужных.
Парсится JSON без проблем, но на выходе мне потом надо иметь всего две вещи: общее количество заказов нужных мне статусов (всего статусов 8, по факту мне надо "брать" только заказы с 3-4, остальные игнорируются), и общую сумму этих заказов. Стоимость всего заказа, к сожалению, получается только суммированием всех товаров из массива (причем, еще и умножением на количество этого товара).
Понятно, что можно нагородить несколько циклов, обрабатывая каждый заказ, откладывая его в определенную таблицу, потом дальше работать с уже "чистой" таблицей. Но что-то мне подсказывает, что есть вариант сделать это намного быстрее.
Если поэтапно:
1. Берем заказ, проверяем статус. Если не подходит, берем следующий. Если подходит, обрабатываем.
2. Считаем общую стоимость заказа (через массив всех товаров в заказе, суммируем и умножаем)
3. Кладем в переменные общее количество подходящих по статусам заказов и общую сумму товаров, входящих в эти заказы.

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

PS. Да, в коде несилен, до этого решал без проблем кубиками, но здесь, думается, можно намного проще.
 

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 794
Благодарностей
2 466
Баллы
113
C#:
{"result":[
    {
    "order_id":111111,
    "status":"cancelled",
    "products":[
        {
        "sku":345345345,
        "quantity":1,
        "price":"300.0000",
        },
        {
        "sku":12312313,
        "quantity":2,
        "price":"300.0000",
        }
        ],
    },
    {
    "order_id":222222,
    "status":"delivering",
    "products":[
        {
        "sku":768678678,
        "quantity":1,
        "price":"1300.0000",
        },
        {
        "sku":456456456,
        "quantity":1,
        "price":"3200.0000",
        }
        ],
    }
]
}
1. Берем заказ, проверяем статус. Если не подходит, берем следующий. Если подходит, обрабатываем.
2. Считаем общую стоимость заказа (через массив всех товаров в заказе, суммируем и умножаем)
3. Кладем в переменные общее количество подходящих по статусам заказов и общую сумму товаров, входящих в эти заказы.
C#:
string json = project.Variables["json"].Value; // в этой переменной json полученный с сайта
List<string[]> list = new List<string[]>(); // сюда будем складывать результат
var data = Global.ZennoLab.Json.JsonConvert.DeserializeObject<dynamic>(json);
for(int i=0; i<data["result"].Count; i++){
    try{
        var result = data["result"][i];
        string order_id = result["order_id"].ToString();
        string status = result["status"].ToString();
  
        if(!(status == "cancelled"|| status == "delivering")) continue; // если не cancelled или delivering - пропускаем ордер
  
        decimal sum_order = 0; 
        for(int j=0; j<result["products"].Count; j++) {
            var products = result["products"][i];
            int quantity = int.Parse(products["quantity"].ToString());
            decimal price = Convert.ToDecimal(products["price"].ToString().Replace(",", "."), System.Globalization.CultureInfo.InvariantCulture);
            sum_order += price*quantity;
        }
        list.Add(new[]{order_id, status, sum_order.ToString()});
    }
    catch(Exception e){
        project.SendErrorToLog(e.Message,true); // в случае ошибки разбора - напишем в лог
    }
}

project.SendInfoToLog(string.Format("Заказов с статусом delivering {0}", list.Where(x=> x[1]== "delivering").Count()));
project.SendInfoToLog(string.Format("Заказов с статусом cancelled {0}", list.Where(x=> x[1]== "cancelled").Count()));
foreach(string[] ss in list) project.SendInfoToLog(string.Join("|", ss),true); // тут делаем с данными что угодно, например выводим в лог или добавляем в список зенно
77792
 
Последнее редактирование:

Moonwalker

Client
Регистрация
16.03.2016
Сообщения
1 674
Благодарностей
1 266
Баллы
113
Ух, завтра в офисе погоняю )) Спасибо.
 

Moonwalker

Client
Регистрация
16.03.2016
Сообщения
1 674
Благодарностей
1 266
Баллы
113
@BAZAg
За заданное направление спасибо, с тестовым примером все работает отлично. Причем, если я какому-нить заказу в тестовом JSON меняю статус на другой (допустим, delivered), то все отрабатывает правильно.
На боевом JSON в небольшом массиве, допустим, два заказа. Один в статусе cancelled, второй в статусе delivered. Если ничего в сниппете не трогать, то находит только cancelled, что верно. Если меняю везде delivering на delivered, то получаю:
77874

Но, в целом, есть, вокруг чего разбираться. Еще раз спасибо за помощь )) Буду копать.
 

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 794
Благодарностей
2 466
Баллы
113
На боевом JSON в небольшом массиве, допустим, два заказа. Один в статусе cancelled, второй в статусе delivered. Если ничего в сниппете не трогать, то находит только cancelled, что верно. Если меняю везде delivering на delivered, то получаю:
Предоставьте в текстовом файле JSON который получили и пытаетесь скормить шаблону.
Предоставьте код с своими изменениями (чтобы можно было посмотреть где была допущена ошибка).
 

soprano

Client
Регистрация
25.08.2011
Сообщения
866
Благодарностей
948
Баллы
93
А вот вылезла такая ошибка
Выполнение действия CSharp OwnCode: JSON+. "Global.ZennoLab.Json.Linq.JValue" не содержит определения для "Count"
или так
Выполнение действия CSharp OwnCode: JSON+. "ZennoLab.JXParser.JsonDynamic" не содержит определения для "Count"
Как поправить?
 
Последнее редактирование:

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)