Filter List Data C# - c#

How can I convert my list of strings:
List<string> appliedFilters = filterString.Split(',').Select(n => n).ToList();
Into a list without duplicates?
My list of strings (appliedFilters) looks like this:
7-27,
2-37,
7-28,
9-18,
9-22,
9-80
I need to output this list without duplicates in the first part of the string, e.g:
7-27-28, 2-37, 9-18-22-80
I'm sure there's a LINQ query here somewhere, but cannot figure it out.

filterString.Split(',')
.Select(s => s.Split('-'))
.GroupBy(ss => ss[0])
.Select(group => string.Join("-", new[]{group.Key}.Concat(group.Select(ss => ss[1])).ToArray()));

Related

Use LINQ to combine a property in a list of lists?

I have a Dictionary that looks like such: Dictionary<Search_Requests, List<Tuple<Search_Subjects, SearchData>>>
In the SearchData class, there's a property called SearchCode. What I want to do is get an array of every search code that appears in this dictionary. I could do this with a few loops, but I'd really prefer to use LINQ. Unfortunately, I can't wrap my mind around how to do this. I tried
RequestDictionary.Select(s => s.Value.Select(z => s.Value.Select(x => x.Item2.SearchCode).ToArray()).ToArray()).ToArray();
But that just got me a string[][][], which isn't close to what I wanted. Can I get a push in the right direction?
You can use .SelectMany() to flatten the results:
RequestDictionary
.SelectMany(s
=> s.Value.SelectMany(z => s.Value.Select(x => x.Item2.SearchCode))
.ToArray();
The trick is to combine .Select() and .SelectMany():
var codes = requestDictionary
//Extract all List<>s from the dictionary and enumerate them back-to-back:
.SelectMany(entry => entry.Value)
//Extract the SearchCode from each list item:
.Select(tuple => tuple.Item2.SearchCode)
.ToArray();

Linq IEnumerable<IGrouping<string, Class>> back to List<Class>

How can I turn the following statement back to List<DocumentData>
IEnumerable<IGrouping<string, DocumentData>> documents =
documentCollection.Select(d => d).GroupBy(g => g.FileName);
the goal is to get List that should be smaller than documentCollection.
FileName contains duplicates so I want to make sure I don't have duplicate names.
I have also tried the following but it's still providing me with duplicate file names
documentCollection =
documentCollection.GroupBy(g => g.FileName).SelectMany(d => d).ToList();
Each IGrouping<string, DocumentData> is an IEnumerable<DocumentData>, so you could simply call SelectMany to flatten the sequences:
var list = documents.SelectMany(d => d).ToList();
Edit: Per the updated question, it seems like the OP wants to select just the first document for any given filename. This can be achieved by calling First() on each IGrouping<string, DocumentData> instance:
IEnumerable<DocumentData> documents =
documentCollection.GroupBy(g => g.FileName, StringComparer.OrdinalIgnoreCase)
.Select(g => g.First())
.ToList();
You haven't said what T should stand for in List<T> you're looking for, so here are couple the most likely to be desired:
List<DocumentData> - rather pointless as you already have that on documentCollection
var results = documents.SelectMany(g => g).ToList();
List<KeyValuePair<string, List<DocumentData>>
var results =
documents.Select(g => new KeyValuePair(g.Key, g.ToList())).ToList();
List<string> - just the names
var results = documents.Select(g => g.Key).ToList();
List<IGrouping<string, DocumentData>>
var results = documents.ToList();

C# - Failed to compare two elements in the array

This is my code:
var distinctDateValues = dt.AsEnumerable()
.Select(row => new
{
Date = DateTime.Parse(row.Field<string>("DAY"))
})
.Distinct()
.ToList();
distinctDateValues.Sort(); // getting error on this line
Values in distinctDateValues are:
The error i am getting is "Failed to compare two elements in the array."
Can anybody suggest me as what i am doing wrong here. I want to sort the values in date column of distinctDateValues.
Needless to create anonymous type, in your case the result distinctDateValues is a list of anonymous type, not a list of DateTime, you should get the sorted list of DateTime like below with OrderBy:
var distinctDateValues = dt.AsEnumerable()
.Select(row => row.Field<DateTime>("DAY"))
.Distinct()
.OrderBy(x => x)
.ToList();
Also, you should use built-in method Field<DateTime> instead of using one more step with DateTime.Parse
Just guessing here... your distinctDateValues don't know how to compare themselves... You would need to implement IComparable or something...
Try this:
var distinctDateValues = dt.AsEnumerable()
.Select(row => DateTime.Parse(row.Field<string>("DAY")))
.Distinct()
.ToList();
distinctDateValues.Sort(); // should not get any errors here...
If you really want to create an anonymous type (e.g., you are only showing us a small part of your code), try this:
var distinctDateValues = dt.AsEnumerable()
.Select(row => new
{
Date = DateTime.Parse(row.Field<string>("DAY"))
})
.Distinct()
.OrderBy(d => d.Date) // do the sorting here with linq
.ToList();

Filter to values in collection in one query

I have the following LINQ query:
List<string> Types = (List<string>)Directory.GetFiles(#"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727")
.Where(x => System.IO.Path.GetFileNameWithoutExtension(x).Contains("Microsoft"))
.ToList<string>();
How could I modify this so it can only get the values stored in a collection, without writing another LINQ query (which I assume will impact performance?)?
Thanks
Try this:
List<String> Types
= Directory.GetFiles(#"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727")
.Where(x => System.IO.Path.GetFileNameWithoutExtension(x).Contains("Microsoft"))
.Where(x => yourCollection.Contains(x))
.ToList();

Split a List of structs into sublists based on the stucts contents

I have a List that I need to split into sublists, one for each value of MyStruct.GroupingString. Can I do this via linq?
somelist.ToLookup(x => x.GroupingString)
List<List<StructType>> groupings = list.GroupBy(x => x.GroupingString)
.Select(x => x.ToList()).ToList();

Categories

Resources