Title pretty much says it. I have two JSON objects and I want to know if they are equal (have all the same property values).
I could stringify them both, but I'm not sure if two equal objects will always produce the same output:
E.g:
{
"firstName": "John",
"lastName": "Smith",
"age": 25,
"favoriteColors": ["blue", "green", "red"]
}
Is a different string from:
{
"age": 25,
"lastName": "Smith",
"firstName": "John",
"favoriteColors": ["blue", "green", "red"]
}
But as objects they have identical properties.
There is a method for this in the Flex SDK. It is in the class ObjectUtil. Here is the description from the source :
/**
* Compares the Objects and returns an integer value
* indicating if the first item is less than greater than or equal to
* the second item.
* This method will recursively compare properties on nested objects and
* will return as soon as a non-zero result is found.
* By default this method will recurse to the deepest level of any property.
* To change the depth for comparison specify a non-negative value for
* the depth parameter.
* #param a Object.
* #param b Object.
* #param depth Indicates how many levels should be
* recursed when performing the comparison.
* Set this value to 0 for a shallow comparison of only the primitive
* representation of each property.
* For example:
* var a:Object = {name:"Bob", info:[1,2,3]};
* var b:Object = {name:"Alice", info:[5,6,7]};
* var c:int = ObjectUtil.compare(a, b, 0);In the above example the complex properties of a and
* b will be flattened by a call to toString()
* when doing the comparison.
* In this case the info property will be turned into a string
* when performing the comparison.
* #return Return 0 if a and b are null, NaN, or equal.
* Return 1 if a is null or greater than b.
* Return -1 if b is null or greater than a.
* #langversion 3.0
* #playerversion Flash 9
* #playerversion AIR 1.1
* #productversion Flex 3
*/
public static function compare (a:Object, b:Object, depth:int=-1) : int;
If you don't want the whole SDK maybe you can just get this function/class and use that source.
You can see the source here. Most of the work is done in the function internalCompare.
Edit: Barış' answer is the best option, as it's tried and tested. Just in case this comes in handy for someone though:
Given that JSON values are limited to a small set of simple types, it should be possible to recurse through the properties fairly easily. Something along these lines works with your example:
private function areEqual(a:Object, b:Object):Boolean {
if (a === null || a is Number || a is Boolean || a is String) {
// Compare primitive values.
return a === b;
} else {
var p:*;
for (p in a) {
// Check if a and b have different values for p.
if (!areEqual(a[p], b[p])) {
return false;
}
}
for (p in b) {
// Check if b has a value which a does not.
if (!a[p]) {
return false;
}
}
return true;
}
return false;
}
Maybe you can convert the two objects to string then compare them
function compareJSON(a:Object, b:Object):Boolean
{
return JSON.stringify(a)===JSON.stringify(b);
}
Related
I'm having trouble understanding the behavior of the code below:
function multiplier(factor){
return number => number * factor;
}
let twice = multiplier(2);
console.log(twice(5));
At the function call multiplier(2), the value of 2 is returned to the binding twice, which is 2, but how so? This implies that the return statement would evaluate to 1 * 2, but the parameter number was never assigned a value. I was expecting undefined * 2, instead which would return undefined. Why is the parameter number assigned a value of 1?
What let twice = multiplier(2); does is stored following function in twice variable
function(number) {
// factor variable value was set here
return number * 2;
}
When you called
console.log(twice(5));
It runs function stored in twice variable as following
function(5) {
return 5 * 2;
}
Hence you got 10 on console.
How can I call assertJsonCount using an indexed, nested array?
In my test, the following JSON is returned:
[[{"sku":"P09250"},{"sku":"P03293"}]]
But attempting to use assertJsonCount returns the following error:
$response->assertJsonCount(2);
// Failed asserting that actual size 1 matches expected size 2.
This may or may not be specific to Laravel. Although a Laravel helper is involved, this issue may occur elsewhere.
assertJsonCount utilises the PHPUnit function PHPUnit::assertCount which uses a laravel helper data_get, which has the following signature:
/**
* Get an item from an array or object using "dot" notation.
*
* #param mixed $target
* #param string|array|int $key
* #param mixed $default
* #return mixed
*/
function data_get($target, $key, $default = null)
{
if (is_null($key)) {
return $target;
}
...
We can see that the JSON returned is a nested array, so logically we should pass in a key of 0.
$response->assertJsonCount($expectedProducts->count(), '0');
However this will be ignored as assertCount function checks if a key has been passed using is_null.
To overcome this, we can count all children of 0:
$response->assertJsonCount($expectedProducts->count(), '0.*');
This will produce the desired result.
I tried to rely on type inference for a function with signature:
proc mode(data: [?]int)
but the compiler said it could not resolve the return type (which is a warning in in itself I guess given there are only two return statements). I tried:
proc mode(data: [?]int): [?]int
but the compiler then said there was an internal error:
internal error: CAL0057 chpl Version 1.13.1.518d486
What is the correct way of specifying that the length of an array returned by a function can only be known at run time?
If the domain/size of the array being returned cannot be described directly in the function prototype, I believe your best bet at present is to omit any description of the return type and lean on Chapel's type inference machinery to determine that you're returning an array (as you attempted). For instance, here is a procedure that reads in an array of previously unknown size and returns it:
proc readArrFromConsole() {
var len = stdin.read(int);
var X: [1..len] real;
for x in X do
x = stdin.read(real);
return X;
}
var A = readArrFromConsole();
writeln(A);
Running it and typing this at the console:
3 1.2 3.4 5.6
Generates:
1.2 3.4 5.6
Your question mentions multiple return statements, which opens up the question about how aggressively Chapel unifies types across distinct arrays. A simple example with multiple arrays of the same type (each with a unique domain, size, and bounds) seems to work:
proc createArr() {
var len = stdin.read(int);
if (len > 0) {
var X: [1..len] real;
return X;
} else {
var Y: [-1..1] real;
return Y;
}
}
var A = createArr();
writeln(A);
To understand why the compiler couldn't resolve the return type in your example may require more information about what your procedure body / return statements contained.
I've come across this from time to time in recursive functions, in situations where omitting the return type fails; in this case I create a record which is an array with its domain, e.g.:
record stringarray {
var D: domain(1);
var strs : [D] string;
}
and then define the recursive array to return one of those records:
proc repeats() : stringarray {
var reps: stringarray;
//...
for child in children do {
childreps = child.repeats();
for childrep in childreps do
reps.push_back(childrep);
}
//...
return reps;
}
I'm trying to define a new type and have not had much luck finding any information about using lists within them. Basically my new type will contain two lists, lets say x and y of type SqlSingle (the user defined type is written in C#) is this even possible?
If not how are you supposed to go about simulating a two lists of an arbitary length in an SQL Server 2008 column?
I'm possibly going about this the wrong way but it is the best approach I can think of at the moment. Any help is very much appreciated.
You can use a List<T> in a CLR UDT - although CLR types are structs, which should be immutable, so a ReadOnlyCollection<T> would be a better choice if you don't have a very compelling reason for the mutability. What you need to know in either case is that SQL won't know how to use the list itself; you can't simply expose the list type as a public IList<T> or IEnumerable<T> and be on your merry way, like you would be able to do in pure .NET.
Typically the way to get around this would be to expose a Count property and some methods to get at the individual list items.
Also, in this case, instead of maintaining two separate lists of SqlSingle instances, I would create an additional type to represent a single point, so you can manage it independently and pass it around in SQL if you need to:
[Serializable]
[SqlUserDefinedType(Format.Native)]
public struct MyPoint
{
private SqlSingle x;
private SqlSingle y;
public MyPoint()
{
}
public MyPoint(SqlSingle x, SqlSingle y) : this()
{
this.x = x;
this.y = y;
}
// You need this method because SQL can't use the ctors
[SqlFunction(Name = "CreateMyPoint")]
public static MyPoint Create(SqlSingle x, SqlSingle y)
{
return new MyPoint(x, y);
}
// Snip Parse method, Null property, etc.
}
The main type would look something like this:
[Serializable]
[SqlUserDefinedType(Format.UserDefined, IsByteOrdered = true, MaxByteSize = ...)]
public struct MyUdt
{
// Make sure to initialize this in any constructors/builders
private IList<MyPoint> points;
[SqlMethod(OnNullCall = false, IsDeterministic = true, IsPrecise = true)]
public MyPoint GetPoint(int index)
{
if ((index >= 0) && (index < points.Count))
{
return points[index];
}
return MyPoint.Null;
}
public int Count
{
get { return points.Count; }
}
}
If you need SQL to be able to get a sequence of all the points, then you can add an enumerable method to the sequence type as well:
[SqlFunction(FillRowMethodName = "FillPointRow",
TableDefinition = "[X] real, [Y] real")]
public static IEnumerable GetPoints(MyUdt obj)
{
return obj.Points;
}
public static void FillPointRow(object obj, out SqlSingle x, out SqlSingle y)
{
MyPoint point = (MyPoint)obj;
x = point.X;
y = point.Y;
}
You might think that it's possible to use an IEnumerable<T> and/or use an instance method instead of a static one, but don't even bother trying, it doesn't work.
So the way you can use the resulting type in SQL Server is:
DECLARE #UDT MyUdt
SET #UDT = <whatever>
-- Will show the number of points
SELECT #UDT.Count
-- Will show the binary representation of the second point
SELECT #UDT.GetPoint(1) AS [Point]
-- Will show the X and Y values for the second point
SELECT #UDT.GetPoint(1).X AS [X], #UDT.GetPoint(1).Y AS [Y]
-- Will show all the points
SELECT * FROM dbo.GetPoints(#UDT)
Hope this helps get you on the right track. UDTs can get pretty complicated to manage when they're dealing with list/sequence data.
Also note that you'll obviously need to add serialization methods, builder methods, aggregate methods, and so on. It can be quite an ordeal; make sure that this is actually the direction you want to go in, because once you start adding UDT columns it can be very difficult to make changes if you realize that you made the wrong choice.
Lists as you describe are usually normalized - that is, stored in separate tables with one row per item - rather than trying to cram them into a single column. If you can share more info on what you are trying to accomplish, maybe we can offer more assistance.
Edit - suggested table structure:
-- route table--
route_id int (PK)
route_length int (or whatever)
route_info <other fields as needed>
-- waypoint table --
route_id int (PK)
sequence tinyint (PK)
lat decimal(9,6)
lon decimal(9,6)
waypoint_info <other fields as needed>
I'm using a shim property to make sure that the date is always UTC. This in itself is pretty simple but now I want to query on the data. I don't want to expose the underlying property, instead I want queries to use the shim property. What I'm having trouble with is mapping the shim property. For example:
public partial class Activity
{
public DateTime Started
{
// Started_ is defined in the DBML file
get{ return Started_.ToUniversalTime(); }
set{ Started_ = value.ToUniversalTime(); }
}
}
var activities = from a in Repository.Of<Activity>()
where a.Started > DateTime.UtcNow.AddHours( - 3 )
select a;
Attempting to execute the query results in an exception:
System.NotSupportedException: The member 'Activity.Started' has no supported
translation to SQL.
This makes sense - how could LINQ to SQL know how to treat the Started property - it's not a column or association? But, I was looking for something like a ColumnAliasAttribute that tells SQL to treat properties of Started as Started_ (with underscore).
Is there a way to help LINQ to SQL translate the expression tree to the Started property can be used just like the Started_ property?
There's a code sample showing how to do that (i.e. use client-side properties in queries) on Damien Guard's blog:
http://damieng.com/blog/2009/06/24/client-side-properties-and-any-remote-linq-provider
That said, I don't think DateTime.ToUniversalTime will translate to SQL anyway so you may need to write some db-side logic for UTC translations anyway. In that case, it may be easier to expose the UTC date/time as a calculated column db-side and include in your L2S classes.
E.g.:
create table utc_test (utc_test_id int not null identity,
local_time datetime not null,
utc_offset_minutes int not null,
utc_time as dateadd(minute, 0-utc_offset_minutes, local_time),
constraint pk_utc_test primary key (utc_test_id));
insert into utc_test (local_time, utc_offset_minutes) values ('2009-09-10 09:34', 420);
insert into utc_test (local_time, utc_offset_minutes) values ('2009-09-09 22:34', -240);
select * from utc_test
Based on #KrstoferA's answer I came up with a reliable solution that hides the fact that the properties are aliased from client code. Since I'm using the repository pattern returning an IQueryable[T] for specific tables, I can simply wrap the IQueryable[T] result provided by the underlying data context and then translate the expression before the underlying provider compiles it.
Here's the code:
public class TranslationQueryWrapper<T> : IQueryable<T>
{
private readonly IQueryable<T> _source;
public TranslationQueryWrapper( IQueryable<T> source )
{
if( source == null ) throw new ArgumentNullException( "source" );
_source = source;
}
// Basic composition, forwards to wrapped source.
public Expression Expression { get { return _source.Expression; } }
public Type ElementType { get { return _source.ElementType; } }
public IEnumerator<T> GetEnumerator() { return _source.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
// Intercept calls to the provider so we can translate first.
public IQueryProvider Provider
{
get { return new WrappedQueryProvider(_source.Provider); }
}
// Another wrapper around the provider
private class WrappedQueryProvider : IQueryProvider
{
private readonly IQueryProvider _provider;
public WrappedQueryProvider( IQueryProvider provider ) {
_provider = provider;
}
// More composition
public object Execute( Expression expression ) {
return Execute( expression ); }
public TResult Execute<TResult>( Expression expression ) {
return _provider.Execute<TResult>( expression ); }
public IQueryable CreateQuery( Expression expression ) {
return CreateQuery( expression ); }
// Magic happens here
public IQueryable<TElement> CreateQuery<TElement>(
Expression expression )
{
return _provider
.CreateQuery<TElement>(
ExpressiveExtensions.WithTranslations( expression ) );
}
}
}
Another example cannot hurt I guess.
In my Template class, I have a field Seconds that I convert to TimeStamp relatively to UTC time. This statement also has a CASE (a?b:c).
private static readonly CompiledExpression<Template, DateTime> TimeStampExpression =
DefaultTranslationOf<Template>.Property(e => e.TimeStamp).Is(template =>
(template.StartPeriod == (int)StartPeriodEnum.Sliding) ? DateTime.UtcNow.AddSeconds(-template.Seconds ?? 0) :
(template.StartPeriod == (int)StartPeriodEnum.Today) ? DateTime.UtcNow.Date :
(template.StartPeriod == (int)StartPeriodEnum.ThisWeek) ? DateTime.UtcNow.Date.AddDays(-(int)DateTime.UtcNow.DayOfWeek) : // Sunday = 0
(template.StartPeriod == (int)StartPeriodEnum.ThisMonth) ? new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1, 0, 0, 0, DateTimeKind.Utc) :
(template.StartPeriod == (int)StartPeriodEnum.ThisYear) ? new DateTime(DateTime.UtcNow.Year, 1, 1, 0, 0, 0, DateTimeKind.Utc) :
DateTime.UtcNow // no matches
);
public DateTime TimeStamp
{
get { return TimeStampExpression.Evaluate(this); }
}
My query to initialize a history-table based on (Event.TimeStamp >= Template.TimeStamp):
foreach (var vgh in (from template in Templates
from machineGroup in MachineGroups
let q = (from event in Events
join vg in MachineGroupings on event.MachineId equals vg.MachineId
where vg.MachineGroupId == machineGroup.MachineGroupId
where event.TimeStamp >= template.TimeStamp
orderby (template.Highest ? event.Amount : event.EventId) descending
select _makeMachineGroupHistory(event.EventId, template.TemplateId, machineGroup.MachineGroupId))
select q.Take(template.MaxResults)).WithTranslations())
MachineGroupHistories.InsertAllOnSubmit(vgh);
It takes a defined maximum number of events per group-template combination.
Anyway, this trick sped up the query by four times or so.