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);
Related
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.
I'm trying to create a list of strings (on a controller method for use as JSON that is consumed by a JQuery Autocomplete on the client). Is there a way to reduce these six or seven lines to two lines? In other words I want the first line to create the IEnumerable of strings.
Also is there a way of not using the custom comparer - all it does is compare strings (on the CompanyMeasureName field).
public JsonResult GetMyMeasureNameList(string term)
{
//I've defined a custom comparer called NameComparer on the MyMeasure Object
IEnumerable<MyMeasure> interList =
MyMeasure.Distinct(new MyMeasure.NameComparer())
.Where(cmo => cmo.CompanyMeasureName
.ToLower()
.Contains(term.ToLower()));
List<string> retList = new List<string>();
foreach (var cmo in interList.ToList())
{
CompanyMeasure c = (CompanyMeasure)cmo;
retList.Add(c.CompanyMeasureName);
}
return Json(retList, JsonRequestBehavior.AllowGet);
}
Thanks in advance
The following solves part of the problem (as usual I came up with the answer 5 seconds after posting the question). However I'd still like to be able to not use a custom comparer as it seems pretty pointless.
IEnumerable<MyMeasure> interList =
MyMeasure.Distinct(new MyMeasure.NameComparer())
.Where(cmo => cmo.CompanyMeasureName
.ToLower()
.Contains(term.ToLower())).Select(m => m.CompanyMeasure);
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.
Let's say I have this method:
public T GetByID(object[] pKeys)
{
DbQuery<T> dbq = mContext.GetDbSet<T>();
return dbq.SingleOrDefault(ent => ent.PrimaryKey.SequenceEqual(pKeys));
}
ent.PrimaryKey is an object[].
Of course, this doesn't work because of the SequenceEqual(). I could maybe use Contains but this would not preserve order: {1, 2} is NOT equal to {2, 1}.
I could also use AsEnumerable() first and then use some logics but that would load the whole table in memory, which is unacceptable.
Is there a way to achieve this?
Edit
I've made the method generic. Because that's what it really is and it makes more sens with the primary key being an array.
I also point out that the goal of the method here could be achieved with mContext.GetDbSet().Find(pKeys). This, however, complicates the use of dbq.Include(property) or mContext.Entry(wanted).Collection(property).Load() for parent.child properties which is another matter not related to the question.
Without reproducible code it is a little tough to test any particular solution, but the first thing that came to my mind (and compiled/tested in notepad) is
public T GetByID(object[] pKeys)
{
DbQuery<T> dbq = mContext.GetDbSet<T>();
for (var i = 0; i < pKeys.length; i++)
{
dbq = dbq.Where(ent => ent.PrimaryKey[i] == pKeys[i]);
}
return dbq.SingleOrDefault();
}
I'm having some trouble figuring out the best way to do this, and I would appreciate any help.
Basically, I'm setting up a filter that allows the user to look at a history of audit items associated with an arbitrary "filter" of usernames.
The datasource is a SQL Server data base, so I'm taking the IQueryable "source" (either a direct table reference from the db context object, or perhaps an IQueryable that's resulted from additional queries), applying the WHERE filter, and then returning the resultant IQueryable object....but I'm a little stumped as to how to perform OR using this approach.
I've considered going the route of Expressions because I know how to OR those, but I haven't been able to figure out quite how to do that with a "Contains" type evaluation, so I'm currently using a UNION, but I'm afraid this might have negative impact on performance, and I'm wondering if it may not give me exactly what I need if other filters (in addition to user name filtering shown here) are added in an arbirary order.
Here is my sample code:
public override IQueryable<X> ApplyFilter<X>(IQueryable<X> source)
{
// Take allowed values...
List<string> searchStrings = new List<string>();
// <SNIP> (This just populates my list of search strings)
IQueryable<X> oReturn = null;
// Step through each iteration, and perform a 'LIKE %value%' query
string[] searchArray = searchStrings.ToArray();
for (int i = 0; i < searchArray.Length; i++)
{
string value = searchArray[i];
if (i == 0)
// For first step, perform direct WHERE
oReturn = source.Where(x => x.Username.Contains(value));
else
// For additional steps, perform UNION on WHERE
oReturn = oReturn.Union(source.Where(x => x.Username.Contains(value)));
}
return oReturn ?? source;
}
This feels like the wrong way to do things, but it does seem to work, so my question is first, is there a better way to do this? Also, is there a way to do a 'Contains' or 'Like' with Expressions?
(Editted to correct my code: In rolling back to working state in order to post it, I apparently didn't roll back quite far enough :) )
=============================================
ETA: Per the solution given, here is my new code (in case anyone reading this is interested):
public override IQueryable<X> ApplyFilter<X>(IQueryable<X> source)
{
List<string> searchStrings = new List<string>(AllowedValues);
// <SNIP> build collection of search values
string[] searchArray = searchStrings.ToArray();
Expression<Func<X, bool>> expression = PredicateBuilder.False<X>();
for (int i = 0; i < searchArray.Length; i++)
{
string value = searchArray[i];
expression = expression.Or(x => x.Username.Contains(value));
}
return source.Where(expression);
}
(One caveat I noticed: Following the PredicateBuilder's example, an empty collection of search strings will return false (false || value1 || ... ), whereas in my original version, I was assuming an empty list should just coallesce to the unfiltered source. As I thought about it more, the new version seems to make more sense for my needs, so I adopted that)
=============================================
You can use the PredicateBuilder from the LINQkit to dynamically construct your query.