Split a LINQ string list - c#

I believe this could be another easy one for you LINQ masters out there.
I have a table with a field that consists of strings delimited by "#". After I select the field using LINQ, how can I split each of the strings into a different list?
My string list looks like:
#A#B#C#D#G#F
I used a simple LINQ query to access this:
from x in Special_texts
where x.Name.Equals("ExceptionList")
select x.Content
In the end, my list should contain:
A
B
C
D
G
F
Thanks in advance.

Assuming you want a single list as output:
var list = Special_texts.Where(x=> x.Name.Equals("ExceptionList"))
.Select(x=> x.Content)
.AsEnumerable()
.Select(x=> x.Split(new [] {'#'}, StringSplitOptions.RemoveEmptyEntries))
.SelectMany(x=> x)
.ToList();
Alternatively if you want a list of lists (one for each item in Special_texts):
var list = Special_texts.Where(x=> x.Name.Equals("ExceptionList"))
.Select(x=> x.Content)
.AsEnumerable()
.Select(x=> x.Split(new [] {'#'}, StringSplitOptions.RemoveEmptyEntries).ToList())
.ToList();

from x in Special_texts
where x.Name.Equals("ExceptionList")
select x.Content.Split('#').ToList();

Related

How to modify string list for duplicate values?

I am working on project which is asp.net mvc core. I want to replace string list of duplicate values to one with comma separated,
List<string> stringList = surveylist.Split('&').ToList();
I have string list
This generate following output:
7=55
6=33
5=MCC
4=GHI
3=ABC
1003=DEF
1003=ABC
1=JKL
And I want to change output like this
7=55
6=33
5=MCC
4=GHI
3=ABC
1003=DEF,ABC
1=JKL
Duplicate items values should be comma separated.
There are probably 20 ways to do this. One simple one would be:
List<string> newStringList = stringList
.Select(a => new { KeyValue = a.Split("=") })
.GroupBy(a => a.KeyValue[0])
.Select(a => $"{a.Select(x => x.KeyValue[0]).First()}={string.Join(",", a.Select(x => x.KeyValue[1]))}")
.ToList();
Take a look at your output. Notice that an equal sign separates each string into a key-value pair. Think about how you want to approach this problem. Is a list of strings really the structure you want to build on? You could take a different approach and use a list of KeyValuePairs or a Dictionary instead.
If you really need to do it with a List, then look at the methods LINQ's Enumerable has to offer. Namely Select and GroupBy.
You can use Select to split once more on the equal sign: .Select(s => s.Split('=')).
You can use GroupBy to group values by a key: .GroupBy(pair => pair[0]).
To join it back to a string, you can use a Select again.
An end result could look something like this:
List<string> stringList = values.Split('&')
.Select(s => {
string[] pair = s.Split('=');
return new { Key = pair[0], Value = pair[1] };
})
.GroupBy(pair => pair.Key)
.Select(g => string.Concat(
g.Key,
'=',
string.Join(
", ",
g.Select(pair => pair.Value)
)
))
.ToList();
The group contains pairs so you need to select the value of each pair and join them into a string.

making a new list with comparing a list with the Field of a Table

I have a list of string
List<string> totalTags =new ({"Test1","test2","Test3","test4","Test5"});
I want to search the table Tags and find list of following Name and make a list for their associated Ids
The Tag Table has two fields ,Id and Name.
like
Id Name
==============
1 Test1
2 Test4
and so on
var IdList= _context.Tags.Where(t2 => !totalTags .Any(t1 => t2.Name.Contains(t1))).Select(p=>p.Id).ToList();
and want to have
IdList ={"1","2",....} (the Id of the rest)
but it doesn't work
You should use Contains method like
var idsList = _context.Tags
.Where(t=> totalTags.Contains(t.Name))
.Select(t=> t.Id)
.ToList()
If you want to select all ids from _context.Tags where tag.Name should present in totalTags list, then try below
var IdList = _context.Tags
.Where(x => totalTags.Contains(x.Name)) //No `!` operator
.Select(x => x.Id)
.ToList();
I think you might want to compare t1 == t2.Name in Any becasue t2.Name is a string instead of list, otherwise that will compare by char.
var IdList = _context.Tags.Where(t2 => totalTags.Any(t1 => t1 == t2.Name)).Select(p => p.Id).ToList();

How to do in this in Linq C#

So far, I have this:
var v = Directory.EnumerateFiles(_strConfigurationFolder)
.GroupBy(x => GetReportName(Path.GetFileNameWithoutExtension(x)));
Configuration folder will contain pairs of files:
abc.json
abc-input.json
def.json
def-input.json
GetReportName() method strips off the "-input" and title cases the filename, so you end up with a grouping of:
Abc
abc.json
abc-input.json
Def
def.json
def-input.json
I have a ReportItem class that has a constructor (Name, str1, str2). I want to extend the Linq to create the ReportItems in a single statement, so really something like:
var v = Directory.EnumerateFiles(_strConfigurationFolder)
.GroupBy(x => GetReportName(Path.GetFileNameWithoutExtension(x)))
**.Select(x => new ReportItem(x.Key, x[0], x[1]));**
Obviously last line doesn't work because the grouping doesn't support array indexing like that. The item should be constructed as "Abc", "abc.json", "abc-input.json", etc.
If you know that each group of interest contains exactly two items, use First() to get the item at index 0, and Last() to get the item at index 1:
var v = Directory.EnumerateFiles(_strConfigurationFolder)
.GroupBy(x => GetReportName(Path.GetFileNameWithoutExtension(x)))
.Where(g => g.Count() == 2) // Make sure we have exactly two items
.Select(x => new ReportItem(x.Key, x.First(), x.Last()));
var v = Directory.EnumerateFiles(_strConfigurationFolder)
.GroupBy(x => GetReportName(Path.GetFileNameWithoutExtension(x))).Select(x => new ReportItem(x.Key, x.FirstOrDefault(), x.Skip(1).FirstOrDefault()));
But are you sure there will be exactly two items in each group? Maybe has it sence for ReportItem to accept IEnumerable, not just two strings?

Query an XML using LINQ and excluding where an Attribute value is equal to that of an Element

I have a LINQ query against an XML, that gives me a list of nested lists, each sublist being a list of an elements("row") attributes.
var items = loadbodies.Descendants("row").Select(a => a.Attributes().Select(b => b.Value).ToList()).ToList();
This works as intended but, what I actually need to is query this against another list of values so as not to have sublists added where one of the elements attributes("messageID") is on the second list. I can do this for one value but need to check it against the entire second list.
The query to exclude a single sublist by a single hardcoded value from the second list is below.
var items = loadbodies.Descendants("row").Where(c => (string)c.Attribute("messageID") != "avaluefromthesecondlist").Select(a => a.Attributes().Select(b => b.Value).ToList()).ToList();
Any help would be much appreciated.
Just use Contains. Note that splitting lines helps readability considerably:
var ids = ...; // Some sequence of ids, e.g. a List<string> or HashSet<string>
var items = loadbodies
.Descendants("row")
.Where(row => ids.Contains((string) row.Attribute("messageId")))
.Select(a => a.Attributes()
.Select(b => b.Value)
.ToList())
.ToList();
Note that you could use a Join call too... but so long as you've got relatively few IDs, this should be fine.

how to get items between the search parameters

Work on C#.I have a list named as InputList .From this list I have to search Some string.After search I want to select all item between the search parameter.Bellow picture discribe in detail.
Text Input File:
Collection :
After read the textFile I store data in dataset then,convert the dataset as collection .From this collection i want to get valuse between the search parameters.
I write the bellow syntax but r3 result can not satisfy me.
var InputList = (from p in ds.Tables["InputFile"].Rows.Cast<DataRow>().ToArray() select p.ItemArray).ToList();
var r3 = (from c in InputList
where c.Any(e => e.ToString().Contains("Loading"))
select c).ToList();
If have any query plz ask.Thanks in advance.
To get the results between queries, the SkipWhile() and TakeWhile() would work (both have variants that give the index to the predicate), but I don't think that is quite what you want given your image.
var loadingIndexes = InputList.Select((r, i) => new { Row=row, Index=i })
.Where(x => x.Row.Any(e =>
e.ToString().Contains("Loading"))
.Select(x => x.Index);
var betweenLines = loadingIndexes
.Select(i => InputList
.Skip(i)
.TakeWhile(r => !r.Any(e =>
e.ToString().Contains("FULL")))
.ToList())
.ToList();
Here betweenLines is a List of Lists of DataRows, where each list is between a DataRow containing the string "Loading" (inclusive) and the next `DataRow" containing the string "FULL" (exclusive).

Categories