Simple Transformation with Linq - linq

I'm sure this is a trivial question but I couldn't find a good example. Suppose all you want to do is change one attribute for all objects in a list. I'd like to say something like:
List<SomeType> list = ...;
list.Select(x => x { x.Name = "Foo" } );
Notice the absence of the "new" keyword. I don't want to recreate objects that already exist, just execute one line of code (in this case a simple assignment) on every element of the list.
Is this possible in linq in some elegant way?
Thanks in advance!

Very easy. MSDN ForEach its actually just a method of the List class, but it allows for you to use Lambda expressions.
list.Foreach(x => x.Name = "Foo" );

It doesn't really fall under Linq if you want to mutate the collection. See Eric Lippert's post to see why.
Try List<T>.ForEach()

Related

Ruby method for values from all associations

This method works, but I'm sure the performance could be greatly improved. Also, I'm realizing how fun and awesome it is to take smelly code like this, and rubify it. But I need a little more help to get my Ruby skills to the level to refactor something like this.
An objective can have "preassign" objectives. These are pre-requisites that must be completed before the a student can try the objective in question.
ObjectiveStudent is the join model between an objective and a student. It has a method called "points_all_time" that finds the student's best score on that objective.
The check_if_ready method is the one that I'm trying to refactor in this question. It also belong to the ObjectiveStudent model.
It needs to check whether the student has passed ALL of the preassigns for a given objective. If so, return true. Return false if the student has a less-than-passing score on any of the preassigns.
def check_if_ready
self.objective.preassigns.each do |preassign|
obj_stud = self.user.objective_students.find_by(objective_id: preassign.id)
return false if obj_stud.points_all_time < 7
end
return true
end
Right now I suspect this method is making too many calls to the database. What I'm really hoping to find is some way to look at the scores for the pre-reqs with a single db call.
Thank you in advance for any insight.
The following should work for you:
def is_ready?
user.objective_students
.where(objective_id: objective.preassigns.select(:id))
.none? { |obj_stud| obj_stud.points_all_time < 7 }
end
We collect all the objective_students for the user where the objective_id is in the list of objective.preassigns ids. This results in one 1 query being executed.
Then we use Enumerable#none? to make sure that none of the objective_students have points_all_time less than 7.
You could also use the inverse .all? { |obj_stud| obj_stud.points_all_time >= 7 } if you wanted
One way you could "rubify" this method is to rewrite the signature as:
def is_ready?
It is common practice to append ? to functions that return a boolean value in Ruby. (Note: I also don't really see a reason to have the word 'check' in the declaration, but that's just an opinion).
Furthermore, if objective_id is the primary key for the objective_students model, you can simply write objective_students.find(preassign.id) instead of the find_by method.
I would also suggest having a separate method for returning a student's points (especially since I suspect you will need to get a student's points more than just once) :
def getPoints(preAssignId)
return self.user.objective_students.find_by(objective_id: preAssignId).points_all_time
end
Then your main method can be written in a more clear, self-describing manner as:
def is_ready?
self.objective.preassigns.each {|preassign| return false if getPoints(preassign) < 7 }
return true
end

Search IList of KeyValuePairs for two keys

I am putting in a temporary fix to code in which we want to validate attributes on an item. These are "swatchImageUrl" and "swatchVariantAttribute". If either one of these is provided, the other must be provided. Where I will check this is on a dictionary of the values. So what I have in place is the following:
if((transformedValues.Any(t => t.Key.Equals("swatchImageUrl")) &&
!transformedValues.Any(t => t.Key.Equals("swatchVariantAttribute"))) ||
(transformedValues.Any(t => t.Key.Equals("swatchVariantAttribute")) &&
!transformedValues.Any(t => t.Key.Equals("swatchImageUrl"))))
{
// throw an error here
}
This feels clunky and possibly inefficient (transformedValues will possibly be a very large list and my understanding is .Any() will end up enumerating the whole list if there are none) but I cannot think of a nicer way of doing this. 'transformedItems' is an IList of string key value pairs (so I can't use .ContainsKey etc.)
Is there some nice neater way of doing this that I am missing? Any insight is much appreciated.
Just in case anyone else is having similar brainfreeze. The obvious way to do this in a better way is as ASh pointed out;
if(transformedValues.Any(t => t.Key.Equals("swatchImageUrl")) != transformedValues.Any(t => t.Key.Equals("swatchVariantAttribute")))
{ /*...*/ }

What is does expression<T> do?

What does Expression<T> do?
I have seen it used in a method similar to:
private Expression<Func<MyClass,bool>> GetFilter(...)
{
}
Can't you just return the Func<MyClass,bool> ?
Google and SO searches have failed me due to the < and > signs.
If TDelegate represents a delegate type, then Expression<TDelegate> represents a lambda expression that can be converted to a delegate of type TDelegate as an expression tree. This allows you to programatically inspect a lambda expression to extract useful information.
For example, if you have
var query = source.Where(x => x.Name == "Alan Turing");
then x => x.Name == "Alan Turning" can be inspected programatically if it's represented as an expression tree, but not so much if it's thought of as a delegate. This is particularly useful in the case of LINQ providers which will walk the expression tree to convert the lambda expression into a different representation. For example, LINQ to SQL would convert the above expression tree to
SELECT * FROM COMPUTERSCIENTIST WHERE NAME = 'Alan Turing'
It can do that because of the representation of the lambda expression as a tree whose nodes can be walked and inspected.
An Expression allows you to inspect the structure of the code inside of the delegate rather than just storing the delegate itself.
As usual, MSDN is pretty clear on the matter:
MSDN - Expression(TDelegate)
Yes, Func<> can be used in place of place of an Expression. The utility of an expression tree is that it gives remote LINQ providers such as LINQ to SQL the ability to look ahead and see what statements are required to allow the query to function. In other words, to treate code as data.
//run the debugger and float over multBy2. It will be able to tell you that it is an method, but it can't tell you what the implementation is.
Func<int, int> multBy2 = x => 2 * x;
//float over this and it will tell you what the implmentation is, the parameters, the method body and other data
System.Linq.Expressions.Expression<Func<int, int>> expression = x => 2 * x;
In the code above you can compare what data is available via the debugger. I invite you to do this. You will see that Func has very little information available. Try it again with Expressions and you will see a lot of information including the method body and parameters are visible at runtime. This is the real power of Expression Trees.

Inject with multiple block parameters

The Sunspot gem for Solr has a method that requires a block with 2 elements:
search.each_hit_with_result do |hit,result|
and I'm using it to build a new hash of results like so:
results = Hash.new
search.each_hit_with_result do |hit,result|
results[result.category.title] = hit.score
end
This is cool and everything but I can't help thinking there is a more 'ruby' way of doing it and I've been looking at the awesome inject method. I think something like the following should be possible but I can't get it to syntactically work. Anyone got any ideas?
search.each_hit_with_result.inject({})
{|newhash,|hit,result||newhash[result.category.title]=hit.score}
I believe that method looks like what do you want:
search.each_hit_with_result.inject({}) { |new_hash, current| new_hash[current[0]] = current[1]; new_hash }
Hope its help you.
Object#enum_for is designed exactly for this:
hit_results = search.enum_for(:each_hit_with_result)
results = Hash[hit_results.map { |hit, res| [res.category.title, hit.score] }]
In my opinion, code should never expose each_xyz methods, they promotes smelly imperative code (as you rightly detected). That kind of methods were understandable when there were no enumerators and you needed to return data lazily, but now it should be considered an anti-pattern. They should return an enumerable or enumerator and let the user decide how to use it.

Linq intersect a child list of integers against a list of integers

I have a list of users each of which contains a list of associated storefront IDs. I have a separate list of integers and I want to find where any storefront id of a user matches any of the integers in the separate list.
I'm expecting something like this:
clientUsers = clientUsers.Where(x => x.Storefronts.Intersect(allowedStorefrontIds));
I'm told the type arguments can't be inferred from the usage on the Where extension method.
Do you know how I should structure my linq in this case?
You just need a .Any() in the lambda to check if the set-intersection contains any elements:
x => x.Storefronts.Intersect(allowedStorefrontIds).Any()
Personally, I would do something like this for efficiency:
var allowedIds = new HashSet<int>(allowedStorefrontIds);
var allowedUsers = clientUsers.Where(x => x.StoreFronts.Any(allowedIds.Contains));
Where expects a function that returns a boolean expression. Intersect returns a list. I think clientUsers.Intersect(allowedStorefrontIds) should return the list you're expecting, unless there is another list not mentioned in the code snippet.

Resources