How to select second string in a list using C#? - c#

I have this code which will sometimes just have one string in it and sometimes have two. Basically when it has two strings I want to be able to select the second string as at the moment it is selecting the first string in the list.
Here is my code:
List<string> workGroupIdStringValues = new List<string>();
workGroupIdStringValues = (List<string>)session["WorkGroupIds"];
List<Guid> workGroupIds = workGroupIdStringValues.ConvertAll<Guid>(workGroupIdStringValue => new Guid(workGroupIdStringValue));
So "workGroupIdStringValues" will sometimes have a second string, how can I select the second and not the first when there is two strings. Is it possible, if so how?
Thanks

Use LINQ's workGroupIdStringValues.Last() to discard all strings but the last one; will work fine if there's just one string.
Update: And then of course you have to adapt the code somewhat:
var workGroupId = new Guid(((List<string>)session["WorkGroupIds"]).Last());

How about
string workGroupIdStringValue = ((List<string>)session["WorkGroupIds"]).Last();

Instead of
List<Guid> workGroupIds = workGroupIdStringValues.ConvertAll<Guid>(workGroupIdStringValue => new Guid(workGroupIdStringValue));
You can do following
Guid workGroupId = new Guid(workGroupIdStringValues[workGroupIdStringValues.Count-1]));

There are a few ways of doing this, I think the best is to do
workGroupIdStringValues.Count will give you the total amount of objects, and
workGroupIdStringValues[1] will return the second entry in your list.
So something like
if(workGroupIdStringValues.Count() > 1)
mystring = workGroupIdStringValues[1];
else
mystring = workGroupIdStringValues[0];

Related

Simple LINQ in string list

A little question for a simple LINQ request. This is my first time with LINQ and still not understand all mechanism.
My structure is something like this
List<string> baseData = new List<string>{"\"10\";\"Texte I need\";\"Texte\"",
"\"50\";\"Texte I need\";\"Texte\"",
"\"1000\";\"Texte I need\";\"Texte\"",
"\"100\";\"Texte I need\";\"Texte\""};
Each line of data is construct with field separator ";" and each field are encapsule with quote ".
I have another List Compose with value i have to find in my first list. And i have the Position in line i have to search. because "Texte I need" can be equal with value i am searching
List<string> valueINeedToFind = new List<string>{"50","100"};
char fieldSeparator = ';';
int fieldPositionInBaseDataForSearch = 0;
int fieldPositionInBaseDataToReturn = 1;
I made a first Linq to extract only Line interested me.
List<string> linesINeedInAllData = baseData.Where(Line => valueINeedToFind.Any(Line.Split(fieldSeparator)[fieldPositionInBaseDataForSearch].Trim('"').Contains)).ToList();
This first request Work Great and now i have only Data Line Interested me.
My problem is I don't want all the line But only a list of the value "Texte I need" in position FieldPositionInBaseDataToReturn.
I have to made another LINQ or can i modify my first to directly get what I need?
Since you will be using the split version of each line more than once, separate out the Split operation and then work on the resulting array:
List<string> linesINeedInAllData = baseData.Select(Line => Line.Split(fieldSeparator))
.Where(splitLine => valueINeedToFind.Any(splitLine[fieldPositionInBaseDataForSearch].Trim('"').Contains))
.Select(splitLine => splitLine[fieldPositionInBaseDataToReturn])
.ToList();
List<string> linesINeedInAllData = baseData.Where(Line => valueINeedToFind.Any(Line.Split(fieldSeparator)[fieldPositionInBaseDataForSearch].Trim('"').Equals)).ToList()
.Select(Line => Line.Split(fieldSeparator)[fieldPositionInBaseDataToReturn].Trim('"').ToList();

If string in list occurs in string, then add to list

had a look around and found many similar questions but none matching mine exactly.
public bool checkInvalid()
{
invalidMessage = filterWords.Any(s => appmessage.Contains(s));
return invalidMessage;
}
If a string is found that matches a string in the list the boolean invalidMessage is set to true.
After this though I would like to be able to add each string found to a list. is there a way I can do this using .Contains() or can someone recommend me another way to go about this?
Many thanks.
Well, from your description, I thought here is what you want:
// Set of filtered words
string[] filterWords = {"AAA", "BBB", "EEE"};
// The app message
string appMessage = "AAA CCC BBB DDD";
// The list contains filtered words from the app message
List<string> result = new List<string>();
// Normally, here is what you do
// 1. With each word in the filtered words set
foreach (string word in filterWords)
{
// Check if it exists in the app message
if (appMessage.Contains(word))
{
// If it does, add to the list
result.Add(word);
}
}
But as you said, you want to use LINQ, so instead of doing a loop, you can do it like this:
// If you want to use LINQ, here is the way
result.AddRange(filterWords.Where(word => appMessage.Contains(word)));
If what you want is to gets the words in filterWords that are contained in appmessage you can use Where:
var words = filterWords.Where(s => appmessage.Contains(s)).ToList();

Linq query, select everything from one lists property that starts with a string in another list

Hello I'm new to linq and lambda
I have two lists
fl.LocalOpenFiles ...
List<string> f....
there is a property (string) for example taking index 0
fl.LocalOpenFiles[0].Path
i wanted to select all from the first list fl.LocalOpenFiles where fl.LocalOpenFiles.Path starts with a string from the List<string> f
I finally got this...
List<LocalOpenFile> lof = new List<LocalOpenFile>();
lof = fl.LocalOpenFiles.Join(
folders,
first => first.Path,
second => second,
(first, second) => first)
.ToList();
But its just selecting folders that meet the requirement first.Path == second and i couldnt find a way to get the data that i want which is something meeting this "braindump" requirement:
f[<any>] == fl.LocalOpenFiles[<any>].Path.Substring(0, f[<any>].Length)
Another Example...
List<string> f = new List<string>{ "abc", "def" };
List<LocalOpenFile> lof = new List<LocalOpenFile>{
new LocalOpenFile("abc"),
new LocalOpenFile("abcc"),
new LocalOpenFile("abdd"),
new LocalOpenFile("defxsldf"),)}
// Result should be
// abc
// abcc
// defxsldf
I hope i explained it in a understandable way :)
Thank you for your help
Do you mean something like this :
List<LocalOpenFile> result =
lof.Where(file => f.Any(prefix => file.Path.StartsWith(prefix)))
.ToList();
You can use a regular where instead of a join, which will give you more straight forward control over the selection criteria;
var result =
from file in lof
from prefix in f
where file.Path.StartsWith(prefix)
select file.Path; // ...or just file if you want the LocalOpenFile objects
Note that a file matching multiple prefixes may show up more than once. If that is a problem, you can just add a call to Distinct to eliminate duplicates.
EDIT:
If you - as it seems in this case - only want to know the matching path and not the prefix it matches (ie you only want data from one collection as in this case), I'd go for #har07's Any solution instead.

How to check for list in LINQ

I am trying to read a file and process using LINQ.
I have a exclude list where if i encounter certain words in the file, i should omit that line
my code is
string sCodeFile = #"C:\temp\allcode.lst";
List<string> sIgnoreList = new List<string>() { "foo.c", "foo1.c" };
var wordsPerLine = from line in File.ReadAllLines(sCodeFile)
let items = line.Split('\n')
where !line.Contains(sIgnoreList.ToString())
select line;
foreach (var item in wordsPerLine)
{
console.WriteLine(item);
}
My LST file looks like below
\voodoo\foo.c
\voodoo\voodoo.h
\voodoo\std.c
\voodoo\foo1.h
in the end i want only
\voodoo\voodoo.h
\voodoo\std.c
How can i process the ignored list in contains? with my above code i dont get the desired output for sure
can any one help?
regards,
Karthik
Revised my answer. The bug is that you're doing a ToString on the ignore list, which certainly will not work. You must check each item in the list, which can be done using something like this:
where !sIgnoreList.Any(ignore => line.Contains(ignore))
A curiosity: since the above lambda is just passing a value into a method that only take the value as a parameter, you can write this even more compact as a method group like this:
where !sIgnoreList.Any(line.Contains)
Try this.
string sCodeFile = #"C:\temp\allcode.lst";
List<string> sIgnoreList = new List<string>() { "foo.c", "foo1.c" };
var wordsPerLine = File.ReadAllLines(sCodeFile).Where(n =>
{
foreach (var ign in sIgnoreList)
{
if (n.IndexOf(ign) != -1)
return false;
}
return true;
});
It passes the current element (n) to a lambda function, which checks it against every element of the sIgnoreList. Returning false means the element is ignored, true means it's returned.
Change it to:
where !sIgnoreList.Contains(line)
You need to compare each single line and check that it doesn't exist in the ignore list.
That's why the Vladislav's answer did not work.
Here's the working solution:
var result = from line in File.ReadAllLines(codeFile)
where !ignoreList.Any(line.Contains)
select line;
The problem was you didn't want to check for the whole path and messed up words/lines part a bit.

Create a list of items within 'var response'

I have the following code:
var request = new GeocodingRequest();
request.Address = postcode;
request.Sensor = "false";
var response = GeocodingService.GetResponse(request);
var result = response.Results. ...?
I'd very much like to get result as a list, but I can't seem to convert it. I know I can do something like response.Results.ToList<string>();, but have had no luck.
Can anyone help please :)
Well you can just use:
GeocodingResult[] results = response.Results;
or
List<GeocodingResult> results = response.Results.ToList();
If you want a list of strings, you'll need to decide how you want to convert each result into a string. For example, you might use:
List<string> results = response.Results
.Select(result => result.FormattedAddress)
.ToList();
It is defined as:
[JsonProperty("results")]
public GeocodingResult[] Results { get; set; }
if you want to make it list call: response.Results.ToList().
But why do you want to make it list? You can insert items into list, but I don't think you need it.
assuming response.Results is IEnumerable, just make sure System.Linq is available as a namespace and say response.Results.ToList()

Categories