Using except operator with property condition - linq

I have two lists with different objects. Both objects have a string property name that I need for comparing.
I need to know what values in list A are not contained in list B based on the name property.
Would the except operator work for this case?
What would be a optimal way to achive this in Linq?

Except operator removes items based on object equality. Although you could shoehorn your scenario into Except by passing an "equality comparer" that pays attention only to Name property, the resultant code would be hard to understand.
A better approach is to make a set of names that you wish to exclude, and use that set in your query:
var excludedNames = new HashSet<string>(listB.Select(item => item.Name));
var result = listA.Where(item => !excludedNames.Contains(item.Name)).ToList();

Related

Mapbox - setFilter expression for 'Contains' name within array of possible values

I'm trying filter my Mapbox layer (mapboxgl) to return just places that start with say 'North', 'South, 'East' or 'West'.
My places are in geojson data as a property.
I'm using map.setFilter with an expression to filter the geojson.
Example:
map.setFilter('markers', ["all",filter1,filter2]);
Where filter2 is a simple check on if the place is 'open' or 'closed' and filter1 is my main filter expression explained below.
The main issue is that the name of the place needs to START with one of these values.
So far I can do this IF the strings to check are all the same length by grabbing the length of the strings and then filtering by that substring of the name.
But this doesn't work (obviously) when I have words that are not the same length.
This is pretty simple in most other languages, but my brain cant figure out this in mapbox's expression filters for some reason!
Here's what I have so far (please excuse the poor code quality here, I'm not a professional coder!!):
//the array data to check for a match
filterArray = ['North','South','East','West'];
//checks first values length - not ideal!
var lengthToCheck = filterArray[0].length;
//apply it to the filter to only return ones starting with X
filter1 = ['in', ['slice',['to-string', ['get', 'name']],0,lengthToCheck], ['literal', filterArray]];
I have to slice the name of the place as it might be for example 'Northampton', which wont be found within the array value[0] being 'North'.
This is equally as bad code for the 'East' values as the name slice is going to be 5 characters, so it will be trying something like 'Eastb' (Eastbourne) within the array value 'East' which just wont work.
It would be good if I could some how flip this round so the filter can check the values in the array within the Name, but I can't figure this out!
Is there a way to do that or is there a magic expression feature I'm missing that would solve this problem?
I'm also going to have the same problem with a 'Contains' type check of an array of values too, but I'll cross that bridge once I figure this part out!
Any help appreciated (before I go putting in some convoluted workaround!).

OCL group by element attribute

In Acceleo I have an OrderedSet of objects, where each object has a string as attribute.
I want to get a container(e.g. OrderedSet) of those strings, where each string is unique.
First, I collect all the strings into an collection ->collect(attribute). Then I convert to an Ordered Set ->asOrderedSet(). This will remove all duplicates.
A String is an (E)DataType rather than an (E)Class instance consequently it has no (e)container. You could do a total model search for all String-typed attributes and check their values - very expensive. Much better to revisit the OrderedSet construction so that the 'container' knowledge is not discarded requiring rediscovery.

How to use .filter() to return a match inside of an array (rethinkdb)

I want to find out how many of my students are being taught by a specific teacher. However some of the students have multiple teachers. The value of the teacher_name entry is represented as an array. The following query only shows those results where the match is exact, that is, it won't show me results where there are multiple teachers.
r.db('client').table('basic_info').filter({teacher_name: ["Andrew McSwain"]});
How can I iterate through the arrays to match if it contains the string I specified? Is there an API command for this or can I use good-ole javascript methods?
You probably want something like:
r.db('client').table('basic_info').filter(function(row) {
return row('teacher_name').contains('Andrew McSwain');
})

How to check whether a value exists in a Ruby structure?

I used to have a series of independent arrays (e.g. name(), id(), description() ). I used to be able to check whether a value existed in a specific array by doing name.include?("Mark")
Now that I moved to a MUCH MORE elegant way to manage different these independent arrays (here for background: How do I convert an Array with a JSON string into a JSON object (ruby)) I am trying to figure out how I do the same.
In short I put all the independent arrays in a single structure so that I can reference the content as object().name, object().id, object().description.
However I am missing now how I can check whether the object array has a value "Mark" in its name structure.
I have tried object.name.include?("Mark") but it doesn't quite like it.
I have also tried to use has_value?but that doesn't seem to be working either (likely because it used to be an hash before I imported it into the structure but right now is no longer a hash - see here: How do I convert an Array with a JSON string into a JSON object (ruby))
Thoughts? How can I check whether object.name contains a certain string?
Thanks.
If you want to find all customers called Mark you can write the following:
customers_named_mark = array_of_customers.select{|c| c.name == 'Mark' }
This will return a potentially empty array.
If you want to find the first customer named Mark, write
customer_named_mark = array_of_customers.detect{|c| c.name == 'Mark' }
This will return the first matching item or nil.

Dynamic number of evaluations on a where (lambda)

I'm new to Entity Framework, LINQ and lambda expressions. I need to do a search over a user's table, and I need to emulate one that already exists on a desktop application. This search gives only 1 text field, and then it takes anything that you put in it and creates a "contains" query on different users' attributes like name, last name, username, etc. The most important part is that if you put two or more words in then the search makes the query search for different words.
Example:
If I search for "ju pe" I will get "Perez, Juan", this works by the identification of blank spaces.
Using regular SQL I can build a regular string containing the query, but how can I do that using lambda?
In other words, how can I get a dynamic number of "evaluations" on the .where()? Like .Where(EV1 || EV2 || EVn)
There is neat library called LinqKit which contains predicatebuilder
Sample code:
var predicate = PredicateBuilder.True <User> ();
predicate = predicate.Or(x => x.Name.Contains("ju"));
predicate = predicate.Or(x => x.Name.Contains("pe"));
// etc ...
Users.AsExpandable().Where(predicate);
You can and/or as much as you like.
You can do this using simple Linq by building a complex Where predicate, if I understand you correctly. Please let me know if I misunderstood you! Let's say you have a string searchTermInput and users, an IEnumerable<User> for some type User with a Name string property. Then you can write:
users.Where(user => searchTermInput.Split(' ')
.All(searchTerm => user.Name.Contains(searchTerm)));
In other words: for each user, check if that user's name contains every one of the search terms and filter it out if it does not.

Resources