Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
221 views
in Technique[技术] by (71.8m points)

C# LINQ split complex joined string data to a List of objects

I've got two classes like this:

class SomeObject_source
{
    public string Model;
    public string Color;
    public string Size;
}

class SomeObject_target
{
    public string Model;
    public string Color;
    public string Size;
    public double Quantity;
    public double Nett;
}

Then we are getting an instance of the SomeObject_source with the following data structure:

    SomeObject_source someObject_source = new SomeObject_source
    {
        Model = "Model_1|Model_2|Model_3|Model_4|Model_5",
        Color = "Black|Black|White|Blue|Red",
        Size = "S^1^0.5|M^2^1.0|L^1^0.6|S^3^1.5|S^1^0.6"
    };

The Size string has the following pattern: size^quantity^nett. But sometimes there is an object with a simple data like:

    SomeObject_source someObject_source = new SomeObject_source
    {
        Model = "Model_1",
        Color = "Black",
        Size = "S"
    };

I'm trying to figure out how do an elegant single LINQ query to split the following data into a List of SomeObject_target, so that the result would be equal to:

    List<SomeObject_target> someObject_Target_List = new List<SomeObject_target>
    {
        new SomeObject_target
        {
            Model = "Model_1",
            Color = "Black",
            Size = "S",
            Quantity = 1,
            Nett = 0.5
        },
        new SomeObject_target
        {
            Model = "Model_2",
            Color = "Black",
            Size = "M",
            Quantity = 2,
            Nett = 1
        },
        new SomeObject_target
        {
            Model = "Model_3",
            Color = "White",
            Size = "L",
            Quantity = 1,
            Nett = 0.6
        },
        new SomeObject_target
        {
            Model = "Model_4",
            Color = "Blue",
            Size = "S",
            Quantity = 3,
            Nett = 1.5
        },
        new SomeObject_target
        {
            Model = "Model_5",
            Color = "Red",
            Size = "S",
            Quantity = 1,
            Nett = 0.6
        },
    };

For now i'm doing as follow:

    char Delimeter_main = '|';
    char Delimeter_inner = '^';
    List<SomeObject_target> someObject_Target_List_ = new List<SomeObject_target>();
    for (int ind = 0; ind < someObject_source.Model.Split(Delimeter_main).Count(); ind++)
    {
        string Model = someObject_source.Model.Split(Delimeter_main)[ind];
        string Color = someObject_source.Color.Split(Delimeter_main)[ind];
        string Size_unparsed = someObject_source.Size.Split(Delimeter_main)[ind];
        if (Size_unparsed.Contains(Delimeter_inner))
        {
            string size = Size_unparsed.Split(Delimeter_inner)[0];
            double quantity = double.TryParse(Size_unparsed.Split(Delimeter_inner)[1], out double _quantity) ? _quantity : 1;
            double nett = double.TryParse(Size_unparsed.Split(Delimeter_inner)[2], out double _nett) ? _nett : 1;
            someObject_Target_List_.Add(new SomeObject_target
            {
                Model = Model,
                Color = Color,
                Size = size,
                Quantity = quantity,
                Nett = nett
            });
        }
        else
        {
            someObject_Target_List_.Add(new SomeObject_target
            {
                Model = Model,
                Color = Color,
                Size = Size_unparsed,
                Quantity = 1,
                Nett = 1
            });
        }
    }

But this obviously looks weird as well as the data architecture overall. Is there any LINQ query to accomplish that in single elegant query?

question from:https://stackoverflow.com/questions/65887531/c-sharp-linq-split-complex-joined-string-data-to-a-list-of-objects

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Normal enumerable.Zip

var result = someObject_source.Model.Split(Delimeter_main)
    .Zip(someObject_source.Color.Split(Delimeter_main), (x, y) => new { x, y })
    .Zip(someObject_source.Size.Split(Delimeter_main), (zip1, z) =>
    {
        var secondSplit = z.Split(Delimeter_inner);
        return new SomeObject_target
        {
            Model = zip1.x,
            Color = zip1.y,
            Size = secondSplit[0],
            Quantity = double.TryParse(secondSplit[1], out double _quantity) ? _quantity : 1,
            Nett = double.TryParse(secondSplit[2], out double _nett) ? _nett : 1,
        };
    });

Extention Method Zip on 3 collection

A little more readable, without the annonymous object wraper for the first Zip result.

var results = someObject_source.Model.Split(Delimeter_main)
    .ZipThree(
        someObject_source.Color.Split(Delimeter_main),
        someObject_source.Size.Split(Delimeter_main), 
        (x, y, z) => {
            var secondSplit = z.Split(Delimeter_inner);
            return new SomeObject_target
            {
                Model = x,
                Color = y,
                Size = secondSplit[0],
                Quantity = double.TryParse(secondSplit[1], out double _quantity) ? _quantity : 1,
                Nett = double.TryParse(secondSplit[2], out double _nett) ? _nett : 1,
            };                    
        }
    );

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...