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();