Home > Software engineering >  How to split object strings to array of object?
How to split object strings to array of object?

Time:06-21

I have a c# object:

var obj = new Item { xcoords="1,2,3", ycoords="5,6,7", zcoords="8,9,4" }

So I want to split this into an array like following:

[
   new Item2 { x=1, y=5, z=8 },
   new Item2 { x=2, y=6, z=9 },
   new Item2 { x=3, y=7, z=4 }
]

Can I do this using Linq? or another way in c#?

CodePudding user response:

Let's create a helper method (either as separate method or as local function):

static IEnumerable<int> ToInts(string s) => s.Split(',').Select(p => Int32.Parse(p));

Putting things together:

var obj = new Item { xcoords = "1,2,3", ycoords = "5,6,7", zcoords = "8,9,4" };

var result = ToInts(obj.xcoords)
    .Zip(ToInts(obj.ycoords), ToInts(obj.zcoords))
    .Select(t => new Item2{ x = t.First, y = t.Second, z = t.Third });

Note: this overload of Zip (since .NET 6?, the doc is wrong on this point) produces tuples with 3 elements named First, Second and Third.

You can append a .ToArray() if you need an array of Coord.


Test assuming that ToString is overridden like this in Item2:

public override string ToString() => $"[{x}, {y}, {z}]";
foreach (var item in result) {
    Console.WriteLine(item);
}

yields:

[1, 5, 8]
[2, 6, 9]
[3, 7, 4]

CodePudding user response:

You don't need LINQ here if coords number is static.

var obj = new Item { xcoords="1,2,3", ycoords="5,6,7", zcoords="8,9,4" };

var xcoords = obj.xcoords.Split(',');
var ycoords = obj.ycoords.Split(',');
var zcoords = obj.zcoords.Split(',');

var result = new Item2[]
{
    new Item2 { x = int.Parse(xcoords[0]), y = int.Parse(ycoords[0]), z = int.Parse(zcoords[0]) },
    new Item2 { x = int.Parse(xcoords[1]), y = int.Parse(ycoords[1]), z = int.Parse(zcoords[1]) },
    new Item2 { x = int.Parse(xcoords[2]), y = int.Parse(ycoords[2]), z = int.Parse(zcoords[2]) },
};

If coords number is dynamic but same for x, y and z then simple "for" loop may resolve the problem.

var obj = new Item { xcoords="1,2,3,4", ycoords="5,6,7,8", zcoords="8,9,4,10" };

var xcoords = obj.xcoords.Split(',');
var ycoords = obj.ycoords.Split(',');
var zcoords = obj.zcoords.Split(',');

var result = new Item2[xcoords.Length];

for (var i = 0; i < xcoords.Length; i  )
{
    result[i] = new Item2
    { 
        x = int.Parse(xcoords[i]),
        y = int.Parse(ycoords[i]),
        z = int.Parse(zcoords[i])
    };
}

LINQ version (Requires .NET 6 or higher. In the previous versions Zip method takes only 2 collections at once.):

var obj = new Item { xcoords = "1,2,3,4", ycoords = "5,6,7,8", zcoords = "8,9,4,10" };

var result = Enumerable
    .Zip(
        obj.xcoords.Split(','),
        obj.ycoords.Split(','),
        obj.zcoords.Split(','),
        (x, y, z) => (x, y, z))
    .Select(
        coord => new Item2
        {
            x = int.Parse(coord.x),
            y = int.Parse(coord.y),
            z = int.Parse(coord.z)
        });

CodePudding user response:

Linq approach https://dotnetfiddle.net/CHizmw

Item obj = new Item { xcoords = "1,2,3", ycoords = "5,6,7", zcoords = "8,9,4" };
Func<string, int[]> GetInt = value => value.Split(',').Select(int.Parse).ToArray();
var helper = new {  xc = GetInt(obj.xcoords), yc = GetInt(obj.ycoords), zc = GetInt(obj.zcoords) };
Item2[] obj2 = Enumerable.Range(0, helper.xc.Length).Select(o =>  new Item2() { x = helper.xc[o], y = helper.yc[o], z = helper.zc[o] }).ToArray();
  • Related