Reputation: 2335
I am currently working on a piece of code that reads in a file line by line, splits it and then stores in a data structure, i.e. I have a single line separated by spaces and I want to split into 13 elements, each corresponding to an item in the struct. I am trying to do this using LINQ with the following data structure:
public struct LogDetails
{
public string LogDate { get; set; }
public string LogTime { get; set; }
public string csMethod { get; set; }
public string csUriStem { get; set; }
public string csUriQuery { get; set; }
public string csUserName { get; set; }
public string cIp { get; set; }
public string csUserAgent { get; set; }
public string csReferrer { get; set; }
public string scStatus { get; set; }
public string scSubStatus { get; set; }
public string scBytes { get; set; }
public string csBytes { get; set; }
}
My LINQ code for reading in the file looks as follows:
var output = inputStream.ReadLine().Split(' ').GroupBy(f => f).AsEnumerable()
.SelectMany(g => g);
When I run this it reads in the line from the file as expected and returns the 13 individual elements I would need to populate the struct. However when I try and retrieve these elements then I hit problems. Ideally, I'd like to be able to do something like the following (non working) piece of code:
IEnumerable<LogDetails> details = inputStream.ReadLine().Split(' ').GroupBy(f => f).AsEnumerable()
.SelectMany(g => new LogDetails
{
LogDate = g.ElementAt(0).ToString(),
LogTime = g.ElementAt(1).ToString()
//rest of the struct goes here
}).ToList();
Any advice appreciated!
Andrew
Thanks everyone for your responses. The completed code, for anyone who is interested is as follows:
IEnumerable<LogDetails> details = null;
details = File.ReadAllLines(pFileName)
.Select(l => new { split = l.Split(' ') })
.Select(s => new LogDetails
{
LogDate = s.split.ElementAtOrDefault(0),
LogTime = s.split.ElementAtOrDefault(1),
csMethod = s.split.ElementAtOrDefault(2),
csUriStem = s.split.ElementAtOrDefault(3),
csUriQuery = s.split.ElementAtOrDefault(4),
csUserName = s.split.ElementAtOrDefault(5),
cIp = s.split.ElementAtOrDefault(6),
csUserAgent = s.split.ElementAtOrDefault(7),
csReferrer = s.split.ElementAtOrDefault(8),
scStatus = s.split.ElementAtOrDefault(9),
scSubStatus = s.split.ElementAtOrDefault(10),
scBytes = s.split.ElementAtOrDefault(11),
csBytes = s.split.ElementAtOrDefault(12)
}).ToList();
Upvotes: 1
Views: 592
Reputation: 3425
Your final solution has some redundancy, just thought to simplify it a bit:
var details =
from line in File.ReadAllLines(pFileName)
let tokens = line.Split(' ')
select new LogDetails
{
LogDate = tokens[0],
LogTime = tokens[1],
csMethod = tokens[2],
csUriStem = tokens[3],
csUriQuery = tokens[4],
csUserName = tokens[5],
cIp = tokens[6],
csUserAgent = tokens[7],
csReferrer = tokens[8],
scStatus = tokens[9],
scSubStatus = tokens[10],
scBytes = tokens[11],
csBytes = tokens[12]
};
Upvotes: 0
Reputation: 460228
I don't know why you want to use the GroupBy
, i would use File.ReadLines
+ Enumerable.Select
:
IEnumerable<LogDetails> details = File.ReadLines(filePath)
.Select(l => new { Split = l.Split() })
.Select(x => new LogDetails
{
LogDate = x.Split.ElementAt(0),
LogTime = x.Split.ElementAtOrDefault(1),
//rest of the struct goes here
});
Upvotes: 4
Reputation: 152616
I'm not sue Linq is your best option here. Linq will loop through each items in the split array. You just need to initilaize an object with the items in the array.
var items = inputStream.ReadLine().Split(' ');
var details new LogDetails {
LogDate = items[0],
LogTime = items[1]
//rest of the struct goes here
};
Upvotes: 2