I have the following piece of code to convert a csv to an XML.
var xml = new XElement("root",
lines.Where((line, index) => index > 0).Select(line => new XElement("TEST",
line.Split(',').Select((column, index) => new XElement(headers[index], column)))))
I do get the big picture here. As in I get what each line does but I do not understand why some part like (line, index) is used. does this mean that when the index>0 then it sets the line to be that respective value?
I'd appreciate if someone can break this down for me. would be great if the lambda expressions are not used.
Firstly, it really helps if you indent more clearly:
var xml = new XElement("root",
lines.Where((line, index) => index > 0) // Skips first line
.Select(line => new XElement("TEST",
line.Split(',')
.Select((column, index) => new XElement(headers[index], column)))))
In Visual Studio I would probably use more horizontal space, putting the line.Split
on the same line as new XElement("TEST")
.
Now, any Where
or Select
call taking a lambda such as (value, index)
received two pieces of information per item:
So .Where((line, index) => index > 0
just means "ignore the first line". It would be more clearly written as .Skip(1)
.
Next, .Select((column, index) => new XElement(headers[index], column))
takes each column, and creates an element with the corresponding header as the element name, and column
as the value. Personally, I'd write this using Zip
, leaving:
var xml = new XElement("root",
lines.Skip(1)
.Select(line => new XElement("TEST",
line.Split(',')
.Zip(headers, (value, header) => new XElement(header, value)))))
See more on this question at Stackoverflow