Ich war mal so frei. Vergleicht die trivialen Typen allerdings als Strings, wo ich mir nicht sicher bin, ob z.b. JSON für Floats einen einheitlichen DecimalSeperator spezifiziert. Die umgekehrte Prüfung konnte man sich doch sparen, indem man vorher die Anzahl der Elemente vergleicht.
Delphi-Quellcode:
type
TJSONType = (
jsonInvalid,
jsonInteger,
jsonFloat,
jsonString,
jsonBoolean,
jsonArray,
jsonObject,
jsonNull
);
TJSONHelper = record
public
class function ValueType(Value: TJSONValue): TJSONType; static;
class function Equals(A, B: TJSONValue): Boolean; static;
end;
class function TJSONHelper.ValueType(Value: TJSONValue): TJSONType;
begin
Result := TJSONType.jsonInvalid;
if (Value is TJSONNumber) then
begin
if (Value.ToString.Contains(GetJSONFormat.DecimalSeparator)) then
begin
Result := TJSONType.jsonFloat;
end else
begin
Result := TJSONType.jsonInteger;
end;
end else
if (Value is TJSONString) then
begin
Result := TJSONType.jsonString;
end else
if (Value is TJSONBool) then
begin
Result := TJSONType.jsonBoolean;
end else
if (Value is TJSONArray) then
begin
Result := TJSONType.jsonArray;
end else
if (Value is TJSONObject) then
begin
Result := TJSONType.jsonObject;
end else
if (Value is TJSONNull) then
begin
Result := TJSONType.jsonNull;
end;
end;
class function TJSONHelper.Equals(A, B: TJSONValue): Boolean;
var
T: TJSONType;
I: Integer;
AA, AB: TJSONArray;
OA, OB: TJSONObject;
P: TJSONPair;
V: TJSONValue;
begin
Result := true;
T := ValueType(A);
if (T <> ValueType(B)) then
begin
Exit(false);
end;
case T of
jsonArray:
begin
AA := A as TJSONArray;
AB := B as TJSONArray;
if (AA.Count <> AB.Count) then
begin
Exit(false);
end;
for I := 0 to AA.Count - 1 do
begin
if (not Equals(AA.Items[I], AB.Items[I])) then
begin
Exit(false);
end;
end;
Exit;
end;
jsonObject:
begin
OA := A as TJSONObject;
OB := B as TJSONObject;
if (OA.Count <> OB.Count) then
begin
Exit(false);
end;
for I := 0 to OA.Count - 1 do
begin
P := OA.Pairs[I];
V := OB.Values[P.JsonString.Value];
if (not Equals(P.JsonValue, V)) then
begin
Exit(false);
end;
end;
Exit;
end;
end;
if (A.Value <> B.Value) then
begin
Exit(false);
end;
end;