How can i retrieve from a List<string> the item(value) that starts with Name=
If the list contains the values:
Name=Jhon Smith
Age=20
Location=CityName
I want to get the value Jhon Smith.
I do know how to traditionally loop through the list using foreach and have a condition if value starts with Name= ... but I'm not that good with LINQ.
This will throw an exception if there is no such element in the collection.
You can use FirstOrDefault and check if you get null or an element to check
whether there was a match or not.
list.First(x => x.StartsWith("Name=")).Substring(5)
This won't throw an exception:
var prefix = "Name=";
var elem = list.FirstOrDefault(item => item.StartsWith(prefix));
if (elem != null) {
return elem.Substring(prefix.Length)
} else {
return null;
}
Use Single or SingleOrDefault like this:
var result = list.Single(s => s.StartsWith("Name=")).Substring(5);
or
string result = string.Empty;
var element = list.SingleOrDefault(s => s.StartsWith("Name="));
if (element == null)
{
//"Name=" not present, throw an exception
}
result = element.Substring(5);
or similarly with First, or FirstOrDefault depending on what you exactly want.
There was another interesting answer by the user canon, but was deleted (I don't know why):
var result = list
.Where(x => x.StartsWith("Name="))
.Select(x => x.Substring(5))
.FirstOrDefault();
Its advantage is that it won't throw regardless of the input data.
String match = list.FirstOrDefault( str => str.IndexOf("Name=", StringComparison.InvariantCulture) > -1 );
return match.Substring("Name=".Length);
Related
This is my code to find string in my UserTable.
var PhoneExists = _db.UserTable.Where(u => u.PhoneNumber == Input.PhoneNumber);
and this is my if code:
if (PhoneExists != null)
{
ErrorAlert("number found.");
return Page();
}
but every time the if condition is true.
It returns true as PhoneExists is not null, but it returns with IQueryable value.
You need to materialize the query to return the result queried from the database.
You may look for .Any() to find whether there is any record with the respective PhoneNumber existed.
bool PhoneExists = _db.UserTable.Any(u => u.PhoneNumber == Input.PhoneNumber);
if (PhoneExists)
{
...
}
Where will always return a non-null enumerable, and it's empty if there are no matches. You have to check its contents. If you expect the phone numbers to be unique, you could use FirstOrDefault or SingleOrDefault to return either a string, or null. The latter will, however, throw if there is more than one match.
You can use Contains here.
Sample code:
var PhoneExists = _db.UserTable.Where(u => u.PhoneNumber.Contains(Input.PhoneNumber)).FirstOrDefault();
In your if code:
if (PhoneExists != null && PhoneExist.Count()== 0)
{
ErrorAlert("number found.");
return Page();
}
You can use Exists instead of Where like this :
if (_db.UserTable.Exists(u => u.PhoneNumber == Input.PhoneNumber))
{
//Do Something
}
About exist checkout https://learn.microsoft.com/tr-tr/dotnet/api/system.collections.generic.list-1.exists?view=net-6.0
You can use FirstOrDefault()
var PhoneExists = _db.UserTable.Where(u => u.PhoneNumber == Input.PhoneNumber).FirstOrDefault();
I want to check if item exists in list, and if it is, push into it a value.
All this, is for avoid from run on the list twice.
Because if I do something like this:
if (Params.Any(p => p.Name == "Phone"))
Params.Where(p => p.Name == "Phone").First().Value = phoneValue
I am run on the list twice. the first time in the any and the second time in the where.
So actually I want to do the both above lines — in one shot.
Is it possible?
You could use FirstOrDefault as follows:
var result = Params.FirstOrDefault(p => p.Name == "Phone");
then check if the value is not null and then set the property:
if(result != null) result.Value = phoneValue;
This way you don't have to enumerate twice over the source.
Please try this:
var parameter = Params.FirstOrDefault(p => p.Name == "Phone");
if (parameter != null) parameter.Value = phoneValue;
A traditional for/foreach loop would be better here as Any and Where will have to iterate the collection two times which might not be what you want in terms of performance.
So do a simple foreach:
foreach(var item in Params)
{
if(item.Name == "phone")
{
item.Value = phoneValue;
break;
}
}
Another posible solution is use Extension Methods
public static class ParametersExtensions
{
public static void SetValue(this List<Parameters> ListParameters, string name, string newValue)
{
var parameter = ListParameters.FirstOrDefault(x => x.Name.Equals(name));
if (parameter != null)
parameter.Value = newValue;
}
}
Then you can use it as belows:
Params.SetValue("Phone", phoneValue);
I have the below code . Here i want to find out servicelevelid in lstServiceLevels List which is an array of objects of ServiceLevelDetails where ServiceLevelName is "Basic"
Could anyone please help me to get it ?
public class ServiceLevelDetails
{
public int servicelevelid;
public string ServiceLevelName;
}
class Program
{
static void Main(string[] args)
{
IList<ServiceLevelDetails> lstServiceLevels = new List<ServiceLevelDetails>();
ServiceLevelDetails one = new ServiceLevelDetails();
one.servicelevelid=1;
one.ServiceLevelName="Basic";
ServiceLevelDetails Two = new ServiceLevelDetails();
Two.servicelevelid = 2;
Two.ServiceLevelName = "Enhanced";
lstServiceLevels.Add(one);
lstServiceLevels.Add(Two);
var test = from LevelName in lstServiceLevels
let LevelName= obj as ServiceLevelDetails
where LevelName.ServiceLevelName == "Basic"
select LevelName;
//getting error in the above code .
}
}
There is nothing in your scope called obj, so it's not clear why this is in your query.
In LINQ query syntax, it sounds like you want this:
from serviceLevel in lstServiceLevels
where serviceLevel.ServiceLevelName == "Basic"
select serviceLevel;
Or in LINQ method syntax:
lstServiceLevels.Where(x => x.ServiceLevelName == "Basic");
If, as you suggest in the comments, you want the id for a specific name:
var id = lstServiceLevels
.Where(x => x.ServiceLevelName == "Basic")
.Select(x => x.servicelevelid)
.Single();
here is an alternative with which you don't run into exceptions
when the element cannot be found.
look for the first occurrence of this element:
// FirstOrDefault will return null if nothing was found
// but it also will return only the first element!
var id_test = lstServiceLevels.FirstOrDefault(x => x.ServiceLevelName == "Basic");
// then you can check for it and take the ID if it was found
// or else assign some other value
int id = id_test != null ? id_test.servicelevelid : 0;
it's of course a matter of taste either to use try/catch or null testing :)
I wanna find the next ID (ID_Titel) by selecting ID_Artiest. I try it by using LINQ (lambda-query). What do I do wrong.
By example:
For ID_Artiest 2, I wanna have ID_Titel n+1.
First I try it without .DefaultIfEmpty(). and then I get a message: Sequence Contains No Element
Second I try it with .DefaultIfEmpty().: And then I get the message: Object reference not set to an instance of an object.
This is the source:
private void UpdateTitel(NoteringDataType itemDezeWeek)
...
...
TitelDataType titel = new TitelDataType();
if (Titelslijst.Count > 0)
titel.ID_Titel = Titelslijst.Where(t => t.ID_Artiest == itemDezeWeek.ID_Artiest).OrderBy(t => t.ID_Titel).DefaultIfEmpty().Max(t => t.ID_Titel) + 1;
else
titel.ID_Titel = 1;
Both of the errors you got are expected if the first Where doesn't find any matching values.
Please try this:
titel.ID_Titel = Titelslijst.Where(t => t.ID_Artiest == itemDezeWeek.ID_Artiest)
.Select(t => t.ID_Titel)
.OrderByDescending(t => t)
.FirstOrDefault() + 1;
Since the Select transforms the collection to an enumeration of ints (I am assuming), the .FirstOrDefault() should return 0 if the Where() didn't return any matches. In your code, .DefaultIfEmpty() would have returned an IEnumerable<T> containing null because it was called on an enumeration of whatever Titelslijst contains.
Apparently the errors you see happen when nothing in the list matches your where condition. DefaultIfEmpty in this case will give you just a single list with null, which does not help a lot.
To avoid such situations you should really assign ID to 1 if there no entries found. So the logic should be like:
TitelDataType titel = new TitelDataType();
int id = 1;
if (Titelslijst.Count > 0)
{
var titles = Titelslijst.Where(t => t.ID_Artiest == itemDezeWeek.ID_Artiest);
if (titles.Any())
id = titles.Max(t => t.ID_Titel) + 1;
}
titel.ID_Titel = id;
More short, more right:
Titelslijst.Where(t => t.ID_Artiest == itemDezeWeek.ID_Artiest).Select(t => t.ID_Artiest).Max();
Data1 = new ObservableCollection<dsData1>(from itmGetAllData2 in GetAllData2
where itmGetAllData2.Name == strName
select itmGetAllData2)[0];
Above LINQ is working fine if there is a match between itmGetAllData2.Name == strName but if there is no record matching strName it is throwing an error.
Can anyone suggest how to handle this? I tried doing
.DefaultIfEmpty().Max(itmGetAllData2 => itmGetAllData2 == null ? "" : itmGetAllData2);
but it's giving casting error.
Your code could be simplified to:
Data1 = GetAllData2.FirstOrDefault(x => x.Name == strName);
If no matches are found, Data1 will be null. (that's what the OrDefault part adds) If you want to substitute a different value for null, you can do, e.g.
Data1 = GetAllData2.FirstOrDefault(x => x.Name == strName) ?? new dsData1();
The reason you are getting this error is because you are trying to access the first element of an empty query.
Use FirstOrDefault
var result = GetAllData2.FirstOrDefault(ad => ad.Name = strName);
if (result != null)
{
// Initalize your ObservableCollection here
}
You get this error when there is no match because [0] is trying to access the first object of a list that doesn't have any objects. Do this instead:
Data1 = GetAllData2.FirstOrDefault(d => d.Name == strName);
This will be the first item like you want, or null if none were found.