WPF开发:如何将IEnumerable生成的集合数据转换为数组或列表并提取Person类字段值
Hey there! Let's walk through how to get your Person collection into a usable list/array, extract specific columns, and leverage LINQ for your views or charts.
Step 1: Convert IEnumerable to a List/Array
Your ReadCSV method returns an IEnumerable<Person>, which is great for lazy loading, but if you want to reuse the data or perform multiple LINQ queries, it's better to convert it to a List<Person> or Person[] first. This enumerates the CSV data once and stores it in memory for easy access.
Modify your MainWindow code to store the collection in a class-level variable (so you can reuse it later):
public partial class MainWindow : Window { // Store the collection for later use in LINQ queries/charts private List<Person> _peopleList; public IEnumerable<Person> ReadCSV(string fileName) { string[] lines = File.ReadAllLines(System.IO.Path.ChangeExtension(fileName, ".csv")); return lines.Select(line => { string[] data = line.Split(','); return new Person(data[0], data[1], data[2], data[3], data[4], data[5], data[6]); }); } public MainWindow() { InitializeComponent(); // Convert IEnumerable to List (use ToArray() if you prefer an array) _peopleList = ReadCSV(@"D:\dato.csv").ToList(); // Assign to ListView as before ListViewPeople.ItemsSource = _peopleList; } }
Step 2: Extract Specific Columns
To pull just the fields you need (like Directory, Name, Event, Type), use LINQ's Select method. You can use anonymous objects for quick one-off tasks, or a custom class if you need to reuse the extracted data.
Using Anonymous Objects (Quick & Simple)
// Extract Directorio and Nombre into a list of anonymous objects var directoryNamePairs = _peopleList.Select(p => new { Directory = p.Directorio, Name = p.Nombre }).ToList(); // Extract Evento and Tipo for charting var eventTypeData = _peopleList.Select(p => new { Event = p.Evento, Type = p.Tipo }).ToList();
Using a Custom DTO (For Reusability)
If you need to pass this extracted data around or use it in multiple places, create a simple Data Transfer Object:
// Define a class for your extracted fields public class PersonSummary { public string Directory { get; set; } public string Name { get; set; } public string Event { get; set; } public string Type { get; set; } } // Convert your list to this structured type var personSummaries = _peopleList.Select(p => new PersonSummary { Directory = p.Directorio, Name = p.Nombre, Event = p.Evento, Type = p.Tipo }).ToList();
Step 3: Query the Collection with LINQ
Now that you have a list, you can use LINQ to filter, group, sort, or aggregate data for your views or charts. Here are some practical examples:
Filter by Event Type
// Get all entries where the event is "Modified" var modifiedEntries = _peopleList.Where(p => p.Evento == "Modified").ToList();
Group by File Type (for a bar chart)
// Group entries by their Tipo and count how many are in each group var typeCounts = _peopleList.GroupBy(p => p.Tipo) .Select(g => new { FileType = g.Key, Count = g.Count() }).ToList();
Sort by Timestamp
// Sort entries by their Time value (ensure your Time string is parseable to DateTime) var sortedByTime = _peopleList.OrderBy(p => DateTime.Parse(p.Time)).ToList();
Step 4: Access Values from IEnumerable Directly
If you ever need to work with the raw IEnumerable<Person> without converting to a list first, remember that IEnumerable is lazy-loaded—it only processes data when you enumerate it (via loops, ToList(), or other LINQ methods). Here's how to access values directly:
IEnumerable<Person> people = ReadCSV(@"D:\dato.csv"); // Get the first entry in the CSV Person firstEntry = people.First(); // Get the entry at index 3 (note: this enumerates up to that point) Person fourthEntry = people.ElementAt(3); // Iterate over all entries foreach (Person person in people) { Console.WriteLine($"{person.Nombre} | {person.Evento}"); }
Keep in mind: each time you iterate over an IEnumerable, it re-runs the underlying logic (re-reading the CSV and splitting lines). Converting to a list once avoids this redundant work.
内容的提问来源于stack exchange,提问作者cbmedins

