Сглаживание JSON -файла c# - уменьшение числа циклов foreach - PullRequest
1 голос
/ 11 марта 2020

Я пытаюсь десериализовать вложенный json -файл, который выглядит следующим образом: Я хочу получить "плоскую" таблицу. Я использую. net 4.0, и у меня нет возможности использовать сторонние библиотеки, такие как json. net.

{
    "responsetime": 33,
    "products": {
        "totalProducts": 25,
        "products": [
            {
                "id": 1,
                "name": "Bike One",
                "colors": [
                    {
                        "colorId": 44,
                        "name": "green",
                        "chemicals": [
                            {
                                "chemicalId": 99,
                                "chemicalName": "abc"
                            },
                            {
                                "chemicalId": 45,
                                "chemicalName": "bcd"
                            }
                        ]
                    },
                    {
                        "colorId": 42,
                        "name": "blue",
                        "chemicals": [
                            {
                                "chemicalId": 96,
                                "chemicalName": "def"
                            },
                            {
                                "chemicalId": 22,
                                "chemicalName": "lkj"
                            }
                        ]
                    }
                ]
            }
        ]
    }
}

Из этого я создал следующие классы:

public class ResponseObject
{
    public int responsetime { get; set; }
    public Products products { get; set; }
}

public class Products
{
    public int totalProducts { get; set; }
    public Product[] products { get; set; }
}

public class Product
{
    public int id { get; set; }
    public string name { get; set; }
    public Color[] colors { get; set; }
}

public class Color
{
    public int colorId { get; set; }
    public string name { get; set; }
    public Chemical[] chemicals { get; set; }
}

public class Chemical
{
    public int chemicalId { get; set; }
    public string chemicalName { get; set; }
}

Вывод, который я хочу, является плоской структурой, подобной следующей:

1 Bike One 44 green 99 abc 
1 Bike One 44 green 45 bcd 
1 Bike One 42 blue  96 def 
1 Bike One 42 blue  22 lkj

Я могу получить это с помощью следующего кода, однако это подразумевает 3 цикла foreach, которые я ' Я боюсь, что это даст плохую производительность, если будет 100 000 продуктов с N цветами и N химикатами каждый. Есть ли другой способ сгладить это, который будет работать лучше, используя «vanilla». net?

            String jsonFileContent = File.ReadAllText(@"C:\example.json"); 
            JavaScriptSerializer js = new JavaScriptSerializer();
            js.MaxJsonLength = Int32.MaxValue;
            ResponseObject rspns = js.Deserialize<ResponseObject>(jsonFileContent);

            foreach (var product in rspns.products.products)
            {
                foreach (var color in product.colors)
                {
                    foreach (var chemical in color.chemicals)
                    {
                        Console.WriteLine(product.id);
                        Console.WriteLine(product.name);
                        Console.WriteLine(color.colorId);
                        Console.WriteLine(color.name);
                        Console.WriteLine(chemical.chemicalId);
                        Console.WriteLine(chemical.chemicalName);
                    }
                }
            }

1 Ответ

0 голосов
/ 11 марта 2020

Вы хотите, чтобы ToString выполнялся теми же объектами:

public class Products
{
    public int totalProducts { get; set; }
    public Product[] products { get; set; }

    public override string ToString(){
        // this iterates all products and stacks their string representation
        var productsStrings = products.Select(x => x.ToString());
        return productsStrings.Aggregate("", (a, n) => a + n + "\n").trimEnd();
    }
}

public class Product
{
    public int id { get; set; }
    public string name { get; set; }
    public Color[] colors { get; set; }

    public override string ToString(){
        // this gets all color strings and prepends the product string
        // "1 Bike" + product (repeated CO times)
        var colorSubstrings = colors.Select(x => x.GetSubstrings());
        var appendOnStrings = colorSubstrings.Select(x => $"{id} {name} {x}");
        return appendOnStrings.Aggregate("", (a, n) => a + n + "\n").trimEnd();
    }
}

public class Color
{
    public int colorId { get; set; }
    public string name { get; set; }
    public Chemical[] chemicals { get; set; }

    public string[] GetSubstrings(){
        // this gets all chemicals strings and prepends the color string
        // "44 green" + chemicalString (repeated CH times)
        return chemicals.Aggregate("", (a, chemical) => a + $"{colorId} {name} {chemical.ToString()} \n").trimEnd();
    }
}

public class Chemical
{
    public int chemicalId { get; set; }
    public string chemicalName { get; set; }

    public override string ToString(){
        // this produces a string like -> "99 abc"
        return $"{chemicalId} {chemicalName}";
    }
}

Затем вы просто анализируете всю цепочку и вызываете ее:

String jsonFileContent = File.ReadAllText(@"C:\example.json");
JavaScriptSerializer js = new JavaScriptSerializer();
js.MaxJsonLength = Int32.MaxValue;

// deserializing JSON to rspns
ResponseObject rspns = js.Deserialize<ResponseObject>(jsonFileContent);

// result will contain the table with all products, colors and chemicals
var result =  rspns.products.ToString();

// printing only once will surely improve the performances
Console.WriteLine(result);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...