Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Json auf Gleichheit prüfen (https://www.delphipraxis.net/194332-json-auf-gleichheit-pruefen.html)

Der schöne Günther 10. Nov 2017 11:04

Delphi-Version: 10 Seattle

Json auf Gleichheit prüfen
 
Kann ich zwei
Delphi-Quellcode:
TJsonObject
-Instanzen auf Gleichheit prüfen? Ich sehe die Methode TJsonObject.Clone(): TJsonAncestor, aber
Delphi-Quellcode:
TObject.Equals(..): Boolean
wurde nicht überschrieben.

Muss man sich das selber basteln?

himitsu 10. Nov 2017 11:06

AW: Json auf Gleichheit prüfen
 
Billiger Trick: Beide JSON-Objekte in JSON-Strings umwandeln und Die dann vergleichen. :stupid:

Der schöne Günther 10. Nov 2017 11:08

AW: Json auf Gleichheit prüfen
 
Aber das scheitert doch schon an der Reihenfolge:

Delphi-Quellcode:
const
   input1 = '{"someNumber": 42, "someText": "Hallo Welt"}';
   input2 = '{"someText": "Hallo Welt", "someNumber": 42}';

sakura 10. Nov 2017 11:16

AW: Json auf Gleichheit prüfen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1385873)
Aber das scheitert doch schon an der Reihenfolge:

Und daran scheitert schon ein genereller Vergleich. Ergo, Du musst Dir diesen Vergleich selbst erstellen und Deine Anforderungen umsetzen.

...:cat:...

P.S.: Logisch sind Deine Beispiele gleich, aber in bestimmten Instanzen mag der gleiche Inhalt mit unterschiedlicher Reihenfolge nicht "gleich genug" sein.

Der schöne Günther 10. Nov 2017 11:26

AW: Json auf Gleichheit prüfen
 
Aber Json ist per Definition nicht geordnet. Klar sind die Strings nicht die selben, aber in Json an sich ist die Reihenfolge doch egal:

Zitat:

An object is an unordered collection of zero or more name/value
pairs, where a name is a string and a value is a string, number,
boolean, null, object, or array.

An array is an ordered sequence of zero or more values.
Quelle: RFC 7159 (Hervorhebung durch mich)

sakura 10. Nov 2017 11:38

AW: Json auf Gleichheit prüfen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1385878)
Aber Json ist per Definition nicht geordnet. Klar sind die Strings nicht die selben, aber in Json an sich ist die Reihenfolge doch egal:

Das ist mir bewusst. Ändert aber nichts daran, das es in den Standard-Bibliotheken keinen Vergleich gibt und Du diesen selbständig machen musst.

...:cat:...

SebastianZ 10. Nov 2017 12:01

AW: Json auf Gleichheit prüfen
 
Das musst du dir selbst basteln.

Mein Ansatz währe hier ein 2-stufiger Vergleich:
1. Die Textlänge des JSON-Strings vergleichen -> unterschiedliche länge, unterschiedliches JSON
2. Die einzelnen Json-Einträge vergleichen. Wie du auf diese Hinkommst ist hier gut ersichtlich:
https://stackoverflow.com/questions/...-in-rad-studio

Zacherl 10. Nov 2017 15:44

AW: Json auf Gleichheit prüfen
 
Zitat:

Zitat von SebastianZ (Beitrag 1385880)
1. Die Textlänge des JSON-Strings vergleichen -> unterschiedliche länge, unterschiedliches JSON

Das mag zwar aus programmiertechnischer Sicht erstmal einfach sein, aber die Performance wird darunter ziemlich leiden, weshalb ich mir diesen Schritt sparen würde.

Der direkte Vergleich aller einzelnen Felder bringt ja auch schon ein eindeutiges Ergebnis. Beachten muss man nur, dass der Vergleich von "beiden Seiten" aus durchgeführt werden muss. Also einmal über die Felder von JSON_1 iterieren und das Vorhandensein + Gleichheit in JSON_2 sicherstellen und danach das selbe Spiel nochmal mit JSON_2 durchführen. Sonst könnte es ja sein, dass JSON_2 zwar die gleichen Felder wie JSON_1 besitzt, aber zusätzlich noch Weitere.

Der schöne Günther 10. Nov 2017 15:53

AW: Json auf Gleichheit prüfen
 
Ja, A und B sind gleich wenn A eine Teilmenge von B und B eine Teilmenge von A ist.

Oder wie der Mathematiker sagen würde:

A=B :⇔ ∀x (x∈A⇔x∈B)


Aber wir müssen hier nicht weiterbohren. Ich bin heute faul. Wenn es etwas fertiges gegeben hätte, dann hätte ich es eingesetzt. Da es nichts gibt, lasse ich die Prüfung ob sie gleich sind halt unter den Tisch fallen...

Zacherl 10. Nov 2017 16:14

AW: Json auf Gleichheit prüfen
 
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;

himitsu 10. Nov 2017 20:54

AW: Json auf Gleichheit prüfen
 
Alternativ erstmal die Elemente der Objekte sortieren und dann vergleichen.

Und nein, bei Objekten kommt es manchmal doch auf die Reihenfolge an, wenn man das auf Property bezieht,
vorallem wenn sich ein Property auf andere Property auswirkt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:54 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz