LINQ Statement dictionary first key's value - linq

I have a dictionary
private Dictionary<string, string> ScannerMessages;
and then I have a call for this
public bool equalMessages()
{
lock (lockObj)
{
return (ScannerMessages.Values.ToList().Distinct().Count() < ScannerMessages.Values.ToList().Count) ? true : false;
}
}
And it returns if the messages are equal. I also need to add to the end of that clause a second check to verify that the values are not null or empty. I was trying to do something like this but I am not sure where to go with the LINQ statement (not the greatest at LINQ)...
public bool equalMessages()
{
lock (lockObj)
{
return ((ScannerMessages.Values.ToList().Distinct().Count() < ScannerMessages.Values.ToList().Count) && (ScannerMessages.Keys.First() *get the value here and check it !null or string.empty) ? true : false;
}
}

To verify all the values are not null or empty:
ScannerMessages.Values.All(s => !string.IsNullOrEmpty(s))
It will return true if all values are not null and not empty.

If you want to get the non-null values you can do this:
ScannerMessages.Values.Where(v=>!string.IsNullOrEmpty(v)).ToList()
or just to get the count
ScannerMessages.Values.Where(v=>!string.IsNullOrEmpty(v)).Count()
or
ScannerMessages[ScannerMessages.Keys.First()].Where(v=>!string.IsNullOrEmpty(v)).Count()

Related

Retrieve single element from LINQ query

Working with LINQ for the first time in a while and trying to clean something up. I have the following statements:
var element = await _Entities.References
.Where(db => db.LoadId == request.LoadId && db.ReferenceCode == "123")
.OrderByDescending(rec => rec.Created).FirstOrDefaultAsync(cancellationToken);
if (element != null) {
dto.ElementValue = element.Value;
}
I'd like to condense this into a single statement if possible but I was having trouble getting just the value from the await method.
You could do something like this:
dto.ElementValue = (await _Entity.References
.Where(db => db.LoadId == request.LoadId && db.ReferenceCode == "123")
.OrderByDescending(rec => rec.Created)
.FirstOrDefaultAsync(cancellationToken))?.Value
?? dto.ElementValue;
Note that technically this changes the behaviour of the code. Previously, if the query doesn't return a result, the ElementValue property is not touched. With a one-liner, if the query doesn't return a result, the ElementValue getter and setter will both be called.
Also, if the query returns a result whose Value is null, the ElementValue property will be set to itself rather than null.

java 8 method reference to: either `equals` or `equalsIgnoreCase`

I tried to convert the body of a method boolean exists(String value, boolean isCaseSensitive) :
for(String str : existingNames){
if(isCaseSensitive ? str.equals(name) : str.equalsIgnoreCase(name)){
return true;
}
}
return false;
to a solution that utilises java8 method references:
Predicate<String> equalityPred = isCaseSensitive ?
name::equals :
name::equalsIgnoreCase;
return existingNames.stream().anyMatch(equalityPred);
Then I saw that this way the equality is performed in the opposite direction (e.g. value.equals(str) ).
Is there a way to fix this and still use method references, and if no what would be the java8 way.
There is no “opposite direction” for equality. The only issue might be the behavior for null values. Your loop might fail, if the collection contains null, your method references will fail, if name is null.
You may achieve the original behavior using lambda expressions:
boolean check(Collection<String> existingNames, String name, boolean isCaseSensitive) {
Predicate<String> equalityPred = isCaseSensitive?
s -> s.equals(name):
s -> s.equalsIgnoreCase(name);
return existingNames.stream().anyMatch(equalityPred);
}
but it makes little sense to consider null for the name parameter, when it will never be equal, as the code will fail with a NullPointerException, if the collection contains null.
To get a sensible behavior for null, you may use
boolean check(Collection<String> existingNames, String name, boolean isCaseSensitive) {
Predicate<String> equalityPred = name==null? Objects::isNull:
isCaseSensitive? name::equals: name::equalsIgnoreCase;
return existingNames.stream().anyMatch(equalityPred);
}
or just
boolean check(Collection<String> existingNames, String name, boolean isCaseSensitive) {
return name==null || isCaseSensitive?
existingNames.contains(name):
existingNames.stream().anyMatch(name::equalsIgnoreCase);
}
If you know that the Collection will never contain null, but want to support null for the name parameter, you could also use
boolean check(Collection<String> existingNames, String name, boolean isCaseSensitive) {
return name!=null && existingNames.stream()
.anyMatch(isCaseSensitive? name::equals: name::equalsIgnoreCase);
}
Well don't use a method reference then and write your lambda directly:
static boolean existsJDK8(List<String> existingNames, String value, boolean isCaseSensitive) {
Predicate<String> equalityPred = isCaseSensitive ? s -> value.equals(s) : s -> value.equalsIgnoreCase(s);
Predicate<String> equalityPredReversed = isCaseSensitive ? s -> s.equals(value) : s -> s.equalsIgnoreCase(value);
// return existingNames.stream().anyMatch(equalityPredReversed);
return existingNames.stream().anyMatch(equalityPred);
}

Elasticsearch: Return empty value from script field

I'm using Elasticsearch, and I have a script field written in Groovy. It needs to replace the value of myField for some values, but I want to let most of the values pass through unchanged. The script below works except for documents that don't have the field at all. How can I make the script field value empty?
if (some criteria) {
return ...; // modified value
}
// This returns 0 if myField doesn't exist
return doc['myField'].value
I can check the empty condition, but I haven't found a way to return an empty value:
if (doc['myField'].empty)
return ???
It's perfectly ok to return null. I think the problem is more in the sequencing of your different test conditions. I've tried to reproduce your issue and I'm able to return null with the following script:
"script_fields": {
"my_script_field": {
"script": "if (doc.myField.empty) { return null } else if (some criteria) { return modifiedValue } else { return doc.myField.value }"
}
}
First check for fields with empty values and return null.
Then, you're guaranteed to have non-empty and existing fields. So you can check for your criteria and return whatever modified field you want.
Finally, you can return the unmodified values for non-empty fields which do not meet your specified criteria.
The script looks like this:
if (doc.myField.empty) {
return null
} else if (some criteria) {
return modifiedValue
} else {
return doc.myField.value
}

.Max() method giving error when used in an if else

My application is in Asp.Net coded in C# and i'm using LINQ for database transactions. My requirement is to get the Max value of the records saved in a certain table, for this i'm using Max() method.
Below is my controller code :
[HttpPost]
public ActionResult Create(Entity_Name Entity_Object)
{
if (Entity_Object.Condition == true)
{
My required code
}
else
{
var get_Max_Number = db.Entity_Name.ToList();
long Max_Number = 0;
if (get_Max_Number.Count() > 0)
{
Max_Number = Convert.ToInt64(get_Max_Number.Max());
}
My required code
}
}
My issue is when i remove the If-else condition then the same Max() method query works perfect, but when i add the If-else statement then i gets the following error.
Error:
At least one object must implement IComparable.
What i tried :
I attempted to remove the If-Else
I placed the Max() method logic above the If-else
Placing the Max() method above If-Else
[HttpPost]
public ActionResult Create(Entity_Name Entity_Object)
{
var get_Max_Number = db.Entity_Name.ToList();
long Max_Number = 0;
if (get_Max_Number.Count() > 0)
{
Max_Number = Convert.ToInt64(get_Max_Number.Max());
}
if (Entity_Object.Condition == true)
{
My required code
}
else
{
My required code
}
}
Max() needs to know what you're getting the maximum of. If you're Entity_Name class contains a number of properties (strings, ints etc...) then you need to tell it what to get the Maximum on the basis of.
Another thing, you're connecting to a DB via Linq from the looks of things, but executing your Count() & Max() functions in memory after you've retrieved the entire contents of the database table. This will be very inefficient as the table grows in size. LinqToSql & LinqToEF support pushing those functions down to the database level. I'd recommend changing your code to the following.
[HttpPost]
public ActionResult Create(Entity_Name Entity_Object)
{
if (Entity_Object.Condition == true)
{
//My required code
}
else
{
long Max_Number = 0;
if(db.Entity_Name.Count() > 0)
{
Max_Number = Convert.ToInt64(
db.Entity_Name.Max(x => x.PropertyToGetMaxOf)
);
}
//My required code
}
}

Linq how to sort and select Distinc in the same line

I appreciate your indication about how to sort on the same line the next instruction.
Thank you very much!
this.ProductosUnicos = this.repository.TemperatureReports.AsEnumerable().Select(tt => tt.Producto).Distinct().ToList();
public List<String> ProductosUnicos
{
get
{
return this._productosunicos;
}
private set
{
if (this._productosunicos == value)
return;
this._productosunicos = value;
this.OnPropertyChanged("ProductosUnicos");
}
}
For sorting there are OrderBy or OrderByDescending extension methods:
reports
.Select(tt => tt.Producto)
.Distinct()
.OrderBy(p => p)
.ToList();
The OrderBy expects an expression that will be evaluated for each item in the sequence. The resulting sequence will be sorted based on the returned value from the expression.

Resources