Scala Linq alternative - c#

I'm trying to re-write an application from .net to Scala, mainly for practice and I've come across this Linq expression that I don't know how to work with. linq is also foreign to me so I'm a little bit out of my depth.
private void DeleteItems(AmazonSimpleDB client, IEnumerable<string> itemNames)
{
var deleteableItems = from n in itemNames select new DeleteableItem()
{
ItemName = n
}
}
I'm looking at some other answers using maps but so far have been unsuccessful, thank you for any help.

It will look something like this:
var deleteableItems = itemNames.map(n -> new DeleteableItem(ItemName = n))
Note that your DeleteableItem should have constructor with ItemName parameter.

Related

C# equivalent of Lambda

I'm trying to convert some JS into C# and i got to this piece but cant figure out what a C# equivalent would be. Hoping someone can point me in the right direction?
I just need help with the contents of these two functions. The $iterator is coded in another spot but im guessing that the C# version of the following code doesnt need it. If you need me to add it, i can.
The context these functions are being called is:
var centers = Lambda.array(Lambda.map(this.hexes,function(hex) {
return me.hexToCenter(hex);
}));
And the functions are:
var Lambda = function() { }
Lambda.array = function(it) {
var a = new Array();
var $it0 = $iterator(it)();
while( $it0.hasNext() ) {
var i = $it0.next();
a.push(i);
}
return a;
}
Lambda.map = function(it,f) {
var l = new List();
var $it0 = $iterator(it)();
while( $it0.hasNext() ) {
var x = $it0.next();
l.add(f(x));
}
return l;
}
You don't really need your own map and array methods. There is already the same functionality available, you just have to add using System.Linq; at the top of your file and you'll be able to use both Select, which is a projection method and ToArray which created an array from your collection. They are both extension methods set on IEnumerable<T>, so you can use them on almost any collection.
var centers = hexes.Select(x => me.hexToCenter(x)).ToArray();
is an equivalent of you JavaScript code:
var centers = Lambda.array(Lambda.map(this.hexes,function(hex) {
return me.hexToCenter(hex);
}));
This looks like a fairly simple C# lambda:
var centers = this.hexes.Select(hex => me.hexToCenter(hex)).ToList();
Select and ToList extension methods are provided by LINQ - you need to add using System.Linq to use them.
You probably want to go the LINQ route here.
Your map is equivalent to LINQ's Select, e.g.
var centers = this.hexes.Select(hex => me.hexToCenter(hex)).ToArray();
The expression hex => me.hexToCenter(hex) is a lambda expression in C#, which Select uses to project this.hexes into your desired form.
ToArray() is equivalent to your Lambda.array call.
101 LINQ Samples in C# is a great resource for examples on using LINQ.
note most of the 101 samples use the query syntax as opposed to the functional syntax I've used above. They are roughly equivalent for simple cases, but being comfortable with the functional syntax shouldn't be a problem for you, coming from JS background.

Searching ElasticSearch using NEST C# Client

I started looking around for a search engine and after some reading I decided going with ElasticSearch (which is quite amazing :)), my project is in C# so I looked around for a client and started using NEST, everything is quite straightforward but I am a bit confused on the searching part.
I want to search all fields on a specific type what I came up with is the following code:
elasticClient.Search<NewType>(s => s.Query(q => q.QueryString(d => d.Query(queryString))));
I saw that much of the string query search is deprecated and wanted to make sure the above is the correct way of doing this (the above is not marked as deprecated...) also it is a bit long for a simple task so maybe anyone knows another way of doing this.
Thanks
I just use the string query version: create my query object using C# anonymous type and serialize it to JSON.
That way, I can have straightforward mapping from all the JSON query examples out there, no need translating into this "query DSL".
Elasticsearch by itself evolves quite rapidly, and this query DSL thus is bound to lack some features.
Edit: Example:
var query = "blabla";
var q = new
{
query = new
{
text = new
{
_all= query
}
},
from = (page-1)*pageSize,
size=pageSize
};
var qJson = JsonConvert.SerializeObject(q);
var hits = _elasticClient.Search<SearchItem>(qJson);
Just to confirm
elasticClient.Search<NewType>(s => s.Query(q => q.QueryString(d => d.Query(queryString))));
Is the preferred way to search and the fact it feels a bit long is because there are alot of options you can play with that are not used here. I'm always open on suggestions to make it shorter!
The string overload is deprecated but wont be removed from NEST. I'll update the obsolete message to explicitly mention this.
If the anonymous types above aren't your thing, you can just use JObjects from json.net and build your query that way. Then you can run it the same way above.
JObject query = new JObject();
query["query"] = new JObject();
query["query"]["text"] = new JObject();
query["query"]["text"]["_all"] = searchTerm;
query["from"] = start;
query["size"] = maxResults;
string stringQuery = JsonConvert.SerializeObject(query);
var results = connectedClient.SearchRaw<SearchItem>(stringQuery);
I like this way better because the DSL in ES uses reserved keywords in C#, like bool, so I don't have to do any escaping.
With ElasticSearch 2.0, I have to use a SearchResponse< NewType > in the Search method like this :
var json = JsonConvert.SerializeObject(searchQuery);
var body = new PostData<object>(json);
var res = _elasticClient.Search<SearchResponse<NewType>>(body);
IEnumerable<NewType> result = res.Body.Hits.Select(h => h.Source).ToList();
Hope it help.
Note: I found very few documentation about PostData class and its generic type parameter

SQL "not in" syntax for Entity Framework 4.1

I have a simple issue with Entity Framework syntax for the "not in" SQL equivalent. Essentially, I want to convert the following SQL syntax into Entity Framework syntax:
select ID
from dbo.List
where ID not in (list of IDs)
Here is a method that I use for looking up a single record:
public static List GetLists(int id)
{
using (dbInstance db = new dbInstance())
{
return db.Lists.Where(m => m.ID == id);
}
}
Here is a pseudo-method that I want to use for this:
public static List<List> GetLists(List<int> listIDs)
{
using (dbInstance db = new dbInstance())
{
return db.Lists.Where(**** What Goes Here ****).ToList();
}
}
Can anyone give me pointers as to what goes in the Where clause area? I read some forums about this and saw mention of using .Contains() or .Any(), but none of the examples were a close enough fit.
Give this a go...
public static List<List> GetLists(List<int> listIDs)
{
using (dbInstance db = new dbInstance())
{
// Use this one to return List where IS NOT IN the provided listIDs
return db.Lists.Where(x => !listIDs.Contains(x.ID)).ToList();
// Or use this one to return List where IS IN the provided listIDs
return db.Lists.Where(x => listIDs.Contains(x.ID)).ToList();
}
}
These will turn into approximately the following database queries:
SELECT [Extent1].*
FROM [dbo].[List] AS [Extent1]
WHERE NOT ([Extent1].[ID] IN (<your,list,of,ids>))
or
SELECT [Extent1].*
FROM [dbo].[List] AS [Extent1]
WHERE [Extent1].[ID] IN (<your,list,of,ids>)
respectively.
This one requires you to think backwards a little bit. Instead of asking if the value is not in some list of ids, you have to ask of some list of id's does not contain the value. Like this
int[] list = new int[] {1,2,3}
Result = (from x in dbo.List where list.Contains(x.id) == false select x);
Try this for starters ...
m => !listIDs.Contains(m.ID)
This might be a way to do what you want:
// From the method you provided, with changes...
public static List GetLists(int[] ids) // Could be List<int> or other =)
{
using (dbInstance db = new dbInstance())
{
return db.Lists.Where(m => !ids.Contains(m.ID));
}
}
However I've found that doing so might raise error on some scenarios, specially when the list is too big and connection is somewhat slow.
Remember to check everything else BEFORE so this filter might have less values to check.
Also remember that Linq does not populate the variable when you build your filter/query (at least not by default). If you're going to iterate for each record, remember to call a ToList() or ToArray() method before, unless each record has 500MB or more...

How does C# lambda work?

I'm trying to implement method Find that searches the database.
I forgot to mention that I'm using Postgresql, so I can't use built in LINQ to SQL.
I want it to be like that:
var user = User.Find(a => a.LastName == "Brown");
Like it's done in List class. But when I go to List's source code (thanks, Reflector), I see this:
public T Find(Predicate<T> match)
{
if (match == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
for (int i = 0; i < this._size; i++)
{
if (match(this._items[i]))
{
return this._items[i];
}
}
return default(T);
}
How can I implement this thing? I need to get those parameters to make the search.
Solution
Okay, I understood now that I need to do LINQ to SQL to do all this good expressions stuff, otherwise I'd have to spend a lot of time reimplementeing the wheel.
Since I can't use LINQ to SQL, I implemented this easy method:
public static User Find(User match, string orderBy = "")
{
string query = "";
if (!String.IsNullOrEmpty(match.FirstName)) query += "first_name='" + match.FirstName + "'";
if (!String.IsNullOrEmpty(match.LastName)) query += "last_name='" + match.LastName+ "'";
return Find(query + (!String.IsNullOrEmpty(orderBy) ? orderBy : ""));
}
This is how to use it:
var user = User.Find(new User { FirstName = "Bob", LastName = "Brown" });
Your method should accept Expression<Func<User>>.
This will give you expression tree instead of delegate which you can analyze and serialize to SQL or convert to any other API call your database have.
If you want everything to be generic, you may wish to go on with implementing IQueryable interface. Useful information can be found here: LINQ Tips: Implementing IQueryable Provider
Although for a simple scenario I would suggest not to complicate everything and stick with using Expression Trees and returning plain IEnumerable<T> or even List<T>.
For your case first version of code could look like this:
public IEnumerable<T> Get(Expression<Func<T, bool>> condition)
{
if (condition.Body.NodeType == ExpressionType.Equal)
{
var equalityExpression = ((BinaryExpression)condition.Body);
var column = ((MemberExpression)equalityExpression.Left).Member.Name;
var value = ((ConstantExpression)equalityExpression.Right).Value;
var table = typeof(T).Name;
var sql = string.Format("select * from {0} where {1} = '{2}'", table, column, value);
return ExecuteSelect(sql);
}
return Enumerable.Empty<T>();
}
And it's complexity grows fast when you want to handle new and new scenarios so make sure you have reliable unit tests for each scenario.
C# Samples for Visual Studio 2008 contain ExpressionTreeVisualizer that will help you to dig into Expression Trees more easily to understand how to extract information you need from it.
And of course, if you can stick with using existing implementation of LINQ, I would suggest to do it. There are Linq to SQL for SQL Server databases, Linq to Entities for many different databases, Linq to NHibernate for NHbernate projects.
Many other LINQ providers can be found here: Link to Everything: A List of LINQ Providers. Amount of work to implement LINQ provider is not trivial so it's a good idea to reuse tested and supported solution.
Exactly the same way. Just replace this._items with your users collection.
Also replace the type parameter T with the type User.
A lambda expression in source code can be converted to either a compiled executable delegate or an expression tree upon compilation. Usually we associate lambda's with delegates but in your case since you say you want access to the parameters (in this case I assume you mean LastName and "Brown" then you want an expression tree.
Once you have an expression tree, you can parse it to see exactly what it is an translate it to whatever you actually need to do.
Here are a few questions about expression trees.
Expression trees for dummies?
Bit Curious to understand Expression Tree in .NET
Sounds like you're definitely reinventing a very complicated wheel though. I'm sure it'll be a useful learning experience, but you should look into LINQ to Entities or LINQ to SQL for real-world programming.
Maybe I just haven't understood the question, but there's already a method for doing what you want: Enumerable.Where.
If you need to find a single element then use SingleOrDefault or FirstOrDefault instead.
You could do it something like this:
public static IEnumerable<User> Find(Predicate<User> match)
{
//I'm not sure of the name
using (var cn = new NpgsqlConnection("..your connection string..") )
using (var cmd = new NpgsqlCommand("SELECT * FROM Users", cn))
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
var user = BuildUserObjectFromIDataRecord(rdr);
if (match(user)) yield return user;
}
}
}
And then you can call it like this
var users = User.Find(a => a.LastName == "Brown");
Note that this returns any number of users, you still have to implement the BuildUserObjectFromIDataRecord() function, and that it will always want to iterate over the entire users table. But it gives you the exact semantics you want.
Okay, I understood now that I need to do LINQ to SQL to do all this good expressions stuff, otherwise I'd have to spend a lot of time reimplementeing the wheel.
Since I can't use LINQ to SQL, I implemented this easy method:
public static User Find(User match, string orderBy = "")
{
string query = "";
if (!String.IsNullOrEmpty(match.FirstName)) query += "first_name='" + match.FirstName + "'";
if (!String.IsNullOrEmpty(match.LastName)) query += "last_name='" + match.LastName+ "'";
return Find(query + (!String.IsNullOrEmpty(orderBy) ? orderBy : ""));
}
This is how to use it:
var user = User.Find(new User { FirstName = "Bob", LastName = "Brown" });
One way would be to create an anonymous delegate, like so:
Predicate<User> Finder = delegate(User user)
{
return user.LastName == "Brown";
}
var User = User.Find(Finder);

Merge two JSON objects programmatically

I have two JSON objects here, generated through the Google Search API. The URL's of these objects can be found below.
http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=hello%20world&rsz=large
http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=hello%20world&rsz=large&start=8
As you can see the first URL returns the first eight results, whilst the second one returns the next eight. Instead of checking these results separately I'd like to programmatically merge them into one JSON object and pass them through as the first sixteen results.
I've attempted this with a couple of extremely simple JSON objects, but what Google returns is still a bit above my head, so I'm hoping for a bit of help with doing such a thing.
As far as I've been told it is not against Google's Terms of Service to merge two objects into one, only that these always go through as two results (which they will). Some friends have pointed me in the direction of automated tools that are capable of doing such things, but I'm yet to find such a tool.
I'm currently working within ASP.NET so C# or VB.NET code is great, but I'm somewhat language independent so any help in any language will be very much appreciated.
Can anyone provide any help and/or advice on doing such a thing?
EDIT: These results will eventually be saved to a database, so any server-side methods would be fantastic, even if it means putting them straight into a table for dealing with later.
function MergeJSON (o, ob) {
for (var z in ob) {
o[z] = ob[z];
}
return o;
}
This looks a lot like the code from Elliot, but is a bit safer in some conditions. It is not adding a function to the object, which could lead to some syntax problems, when used in with a framework like Extjs or jQuery. I had the problem that it gave me problems in the syntax when used in an event listener. But credits go to Elliot, he did the job.
Use this as following:
a = {a : 1}
b = {b : 2}
c = {c : 3}
x = MergeJSON ( a, b);
x = MergeJSON ( x, c);
result : x == {a : 1, b : 2, c : 3}
Thank you Elliot
Object.prototype.merge = (function (ob) {
var o = this;
var i = 0;
for (var z in ob) {
if (ob.hasOwnProperty(z)) {
o[z] = ob[z];
}
}
return o;
})
var a = {a:1}
var b = {b:2}
var c = a.merge(b); // === {a:1,b:2}
Rather than merge the two results together, I just decided to parse them, then link those two together. In the end there was really no need to merge the two together when they could be easily joined within a database.
If you are up to a client side solution(JavaScript actually) what about trying the "unite" function I have written: http://code.google.com/p/av-jslib/source/browse/js/aV.ext.object.js#36
With Jquery you could do this!
a = $.extend({a:1}, {b:2});
result: Object { a=1, b=2}
http://api.jquery.com/jQuery.extend/
Also, if you really want to do the results manipulation server-sided, this article seems to give a pretty reasonable walkthrough of the process.
I'm not sure how you'd merge these things completely, given that there's a lot of extra data in each apart from the results themselves, but if you just want a JavaScript array containing all 16 results, this should work...
var responses = [GetJsonObjectFromThatUriUsingJqueryOrSomething(),
GetJsonObjectFromThatOtherUriUsingJqueryOrSomething()];
// Probably want to check for success
// and ensure that responses[i].responseData.results is valid.
var results = [];
for (var i = 0; i < responses.length; ++i)
{
results = results.concat(responses[i].responseData.results);
}
To make it more neat, you can add the merge function to the JSON object.
This is the solution from Johan van de Merwe based on Elliot's answer, added to the actual JSON object.
// Extend JSON object
JSON.merge = function (o,ob) {
for (var z in ob) {
o[z] = ob[z];
}
return o;
}
json3 = JSON.merge(json1,json2);

Categories