php.de

Zurück   php.de > Webentwicklung > JavaScript, Ajax und mehr

JavaScript, Ajax und mehr dynamisches Scripten und Interaktion auf Clientebene

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 04.09.2011, 18:07  
Neuer Benutzer
 
Registriert seit: 05.03.2011
Beiträge: 16
PHP-Kenntnisse:
Fortgeschritten
laszlokorte befindet sich auf einem aufstrebenden Ast
Standard Diff Object-Array

Guten Tag zusammen,

ich habe mal wieder ein kleines aber vielleicht interessantes Problem.
Eigentlich ist es sprachenunabhängig, aber umgesetzt werden soll es in Javascript, daher poste ich es hier.

Ich habe folgende Datenstruktur:
Code:
structure = [
   { 'intern_id' : 1 },
   { 'intern_id' : 2 },
   { 'intern_id' : 3 },
   { 'intern_id' : 4 },
   { 'intern_id' : 5 }
];
Also ein Array an Objekten. Jedes dieser Objekte hat eine ID-Property, die als einzigartig zu betrachten ist.

Ich möchte nun zwei dieser Strukturen vergleichen und dabei eben nur nur in Bezug auf den Index des Arrays, sondern mit Bezugnahme auf die id des Objekts.

Wenn ich also in der oben genannten Struktur das 5. Objekte an den Anfang schiebe und das Resultat dann mit der Ausgangsstruktur vergleiche, möchte ich die Information haben, dass sich die Objekte mit den IDs 1-4 nicht geändert haben, aber das objekt mit der ID 5 von der 5. an die erste Stelle geschoben wurde.
Neben dem verschieben von Objekten im Array, soll natürlich auch das Hinzufügen und entfernen von Objekten erkannt werden.

Das Ergebnis des Vergleiches hätte ich gerne in einem solchen Format:
(Angenommen zusätzlich zu dem verschobenen Objekt[id:5] wird Objekt[ID:3] noch gelöscht und am ende noch ein Objekt hinzugefügt, was dann die ID6 bekommt)

Code:
old_structure = [
   { 'intern_id' : 1 },
   { 'intern_id' : 2 },
   { 'intern_id' : 3 },
   { 'intern_id' : 4 },
   { 'intern_id' : 5 }
];

new_structure = [
   { 'intern_id' : 5 },
   { 'intern_id' : 1 },
   { 'intern_id' : 2 },
   { 'intern_id' : 4 },
   { 'intern_id' : 6 }
];
Code:
diff = [
  {'change': 'moved_to_here', 'object': { 'intern_id': 5 }, 'changed_props': []},
  {'change': 'none', 'object': { 'intern_id': 1 }, 'changed_props': []},
  {'change': 'none', 'object': { 'intern_id': 2 }, 'changed_props': []},
  {'change': 'deleted', 'object': { 'intern_id': 3 }, 'changed_props': []},
  {'change': 'none', 'object': { 'intern_id': 4 }, 'changed_props': []},
  {'change': 'move_from_here', 'object': { 'intern_id': 5 }, 'changed_props': []},
  {'change': 'added', 'object': { 'intern_id': 6 }, 'changed_props': []}
]
Die changed_props-Property ist für das aktuelle Problem erstmal egal, später sollen aber für moved und none-changed noch die evtl veränderten (weiteren) Properties der Objekte gelistet werden.

Ich stelle mir vor, dass es für so ein Problem schon irgendwo einen Algorithms gibt, habe aber noch nichts gefunden. Vielleicht hat von euch ja jemand einen Tipp.

Einerseits ist das ganze ja durch das movement-tracking etwas komplexer als ein einfacher Text-Line-Diff, andererseits dürften die vorhandenen eindeutigen IDs das ganze evtl. ja auch vereinfachen.
laszlokorte ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 04.09.2011, 18:12  
Moderator¹
 
Registriert seit: 28.03.2010
Beiträge: 7.470
PHP-Kenntnisse:
Fortgeschritten
ChrisB ist ein wunderbarer AnblickChrisB ist ein wunderbarer AnblickChrisB ist ein wunderbarer AnblickChrisB ist ein wunderbarer AnblickChrisB ist ein wunderbarer AnblickChrisB ist ein wunderbarer AnblickChrisB ist ein wunderbarer Anblick
Standard

Zitat:
Zitat von laszlokorte Beitrag anzeigen
Wenn ich also in der oben genannten Struktur das 5. Objekte an den Anfang schiebe und das Resultat dann mit der Ausgangsstruktur vergleiche, möchte ich die Information haben, dass sich die Objekte mit den IDs 1-4 nicht geändert haben
Das wäre aber doch gar nicht mehr der Fall - weil Objekt 1 jetzt nicht mehr an Position 1, sondern an Position 2 steht.
__________________
RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
ChrisB ist offline   Mit Zitat antworten
Alt 04.09.2011, 18:44  
Neuer Benutzer
 
Registriert seit: 05.03.2011
Beiträge: 16
PHP-Kenntnisse:
Fortgeschritten
laszlokorte befindet sich auf einem aufstrebenden Ast
Standard

Das stimmt natürlich. Es ist aber ein Teil des Problems, das richtig zu erkennen, denn wenn ich oben ein Objekt einfüge, ist es uninteressant für den Betrachter des Diffs, dass sich der Rest nach unten bewegt. Ansonsten würde ja bei fast egal welcher Änderung an der Struktur die gesamte Struktur als "geändert" markiert werden, sodass niemand mehr erkennt, was sich nun wirklich geändert hat.

Das Tracking des Moved-To und Moved-From soll nur für die Objekte stattfinden, die sich "tatsächlich" bewegt haben. Natürlich ist mir klar, dass Bewegung relativ ist und sich je nach Sichtweise immer genau das andere Objekt bewegt oder hier eben "alles" bewegt.

Wenn man das ganze aber als DAU betrachtet, ist in dem obigen Beispiel die einfachste Schlussfolgerung, dass sich Objekt5 nach oben bewegt hat.
Wie man das jetzt im Programm erkennt ist die Frage. Da ich noch nie einen Diff-Programmiert hab, bin ich auf diesem Gebiet noch mehr in der Denkweise des Benutzers als in der Logik der Datenstrukturen. Ich habe eine Vorstellung davon, wo ich hin will, aber bin gar nicht 100% sicher, ob oder wie das möglich ist.

Wenn man einen Text-Diff macht, wird ja auch erkannt, dass 5 Zeilen am Anfang der Datei eingefügt wurden und entsprechend davon abgeleitet, dass sich die anderen Zeilen obwohl sie nicht mehr an der gleichen Position sind, nicht geändert haben.
laszlokorte ist offline   Mit Zitat antworten
Alt 04.09.2011, 21:44  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Zitat:
Wenn man einen Text-Diff macht, wird ja auch erkannt, dass 5 Zeilen am Anfang der Datei eingefügt wurden und entsprechend davon abgeleitet, dass sich die anderen Zeilen obwohl sie nicht mehr an der gleichen Position sind, nicht geändert haben.
Nicht immer. Das kommt stark auf den eingefügten Text an. Enthält der Fragmente aus dem bisherigen, sieht ein Diff auch schnell mal ganz anders aus. Fazit: Entweder musst Du viel Gehirmschmalz investieren, oder das Problrm ist ne Nummer zu groß für Dich. In jedem Fall wüßte ich nicht, was dieses Board jetzt für Dich tun soll.

http://neil.fraser.name/writing/diff/ Viel Spaß.
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist offline   Mit Zitat antworten
Alt 04.09.2011, 23:42  
Moderator
 
Benutzerbild von Chriz
 
Registriert seit: 11.05.2008
Beiträge: 6.266
Chriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer Anblick
Standard

Hab nur den ersten Block deines Postings gelesen, aber wenn du eine PHP-Funktion suchst, wahrscheinlich array_diff_assoc, kannst du immer mal bei phpjs.org vorbeischauen:
http://phpjs.org/functions/array_diff_assoc:310

PS: Kann mir jemand die Syntax dort erklaeren .. arr1keys: for (k1 in arr1)???
__________________
"Nuschel ich?" - "Was?"
Chriz ist offline   Mit Zitat antworten
Alt 04.09.2011, 23:43  
Neuer Benutzer
 
Registriert seit: 05.03.2011
Beiträge: 16
PHP-Kenntnisse:
Fortgeschritten
laszlokorte befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Enthält der Fragmente aus dem bisherigen, sieht ein Diff auch schnell mal ganz anders aus.
Ich hab nun aber pro "zeile" eine eindeutige id, die nicht doppelt vor kommt.

Zitat:
In jedem Fall wüßte ich nicht, was dieses Board jetzt für Dich tun soll.
Dein Link sieht schon mal recht interessant aus. Ich hab nicht wirklich erwartet, dass hier jemand sofort mit einer einfachen Lösung ankommt.
Aber es könnte ja sein, dass diese Art von Diff einen besonderen Namen hat, nach dem man besser googlen kann oder es vielleicht einen Algorithmus, der genau so etwas tut schon in pseudo-code gibt.

Anfangs kam mir das Problem gar nicht so komplex vor, nach etwas experimentieren habe ich gemerkt, dass es nicht ganz so einfach ist wie ich dachte. Wenn das Ganze in ein paar hundert Zeilen Code gut und performant zu machen ist, wäre das ja schonmal gut. Wenn's auch mit weniger geht noch besser. Wenn es eher eine Sache ist, über die man ein ganzes Buch schreiben könnte, dann muss ich das Problem wohl vereinfachen und mich mit weniger komfort begnügen.

Bisher habe ich mir grob so etwas gedacht:

- Über die neue Struktur iterieren
- alle objekt-ids, die auch in der alten vorkommen in einem array sammeln.

- über die alte Struktur iterieren
- alle objekt-ids, die auch in der neuen Version vorkommen, in einem zweiten array sammeln

- jetzt habe ich die alle Objekte, die nicht gelöscht und nicht hinzugefügt wurden (also alle gemeinsamen), einmal in der Reihenfolge, wie sie früher waren und einmal in der neuen Reihenfolge

- ein drittes - leeres - Array namens "result" erzeugen
- Einmal von 0 bis n hoch zählen, wobei n die länge der längeren der beiden Strukturen ist, den Zähler nenne ich mal i
-- Dabei erst die alte Struktur betrachten:
--- Wenn das i'te Objekt der alten Struktur in der neuen nicht vorkommen, dieses als "deleted" ins result pushen
--- Ansonsten als "not modified" oder "moved_from" pushen. Diese Entscheidung anhand der beiden zu anfangs erzeugen Arrays mit der alten und neuen Reihenfolge der ObjektIds treffen. Wie genau weiss ich eben noch nicht
-- Als nächstes die neue Struktur betrachten.
--- Wenn das i'te Objekt der neuen Struktur in der alten nicht vorkam, dieses als "added" ins result pushen
--- Ansonsten als "moved_to" pushen, wenn dieses Objekt nicht schon als "not modified" gepusht wurde oder wenn sich die Reihenfolge - anhand der zwei arrays ermittelt - nicht geändert hat

Bei der Erkennung, ob sich die Reihenfolge nun geändert hat oder nicht, hakt es eben noch.

/edit: @chriz: Die Syntax hat mich grad auch erst verwundert. Dort wird der äußeren for-schleife ein Label gegeben, damit das continue in der inneren schleife auf die äussere angewendet werden kann. Alternativ könnte man auch mit continue 1; oder continue 2; angeben, in der wievielten schleife von innen gezählt man in die nächste iteration springen will. Ist aber glaube ich nicht ganz das was ich brauche, trotzdem danke.

Geändert von laszlokorte (05.09.2011 um 00:03 Uhr).
laszlokorte ist offline   Mit Zitat antworten
Alt 05.09.2011, 00:17  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Zitat:
PS: Kann mir jemand die Syntax dort erklaeren .. arr1keys: for (k1 in arr1)???
arr1keys: ist die Sprungmarke (vgl. continue weiter unten) *)
for (k1 in arr1) iteriert über arr1 und liefert die Schlüssel (ähnlich foreach, aber eben nur für Objektschlüssel).

[edit]
*) nennt sich wohl „label“: http://www.mediaevent.de/javascript/...Schleifen.html
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist offline   Mit Zitat antworten
Alt 05.09.2011, 01:06  
Neuer Benutzer
 
Registriert seit: 05.03.2011
Beiträge: 16
PHP-Kenntnisse:
Fortgeschritten
laszlokorte befindet sich auf einem aufstrebenden Ast
Standard

Ich habe grad noch mal nachgedacht. Ich denke man könnte das Problem so weiter reduzieren dass man sagt:

Ich habe zwei Arrays mit gleicher Länge, gleichem Inhalt, aber in verschiedener Reihenfolge und suche die kleinste Menge an Elementen, die ich bewegen müsste um das eine Array in das andere umzuwandeln.

Code:
f([a,b,c,d], [a,c,d,b]) # => [b]
laszlokorte ist offline   Mit Zitat antworten
Alt 05.09.2011, 01:43  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Ja, das ist schon klar. Das Problem ist halt, dass die Lösung nur trivial ist, wenn Du mit atomaren Vorgängen arbeitest*). Also eine Änderung pro Diff. Wie ich das verstehe, willst Du aber zwei Strukturen in den Prozess reinwerfen und die optimale Überführung errechnen lassen. Das scheint mir recht aussichtslos.

PS: Was ich auf jeden Fall machen würde: Nicht zwischen Löschen und Verschieben unterscheiden. Verschieben als Löschen und Einfügen zu begreifen, macht die Sache auf jeden Fall einfacher. Im Endeffekt kannst Du dazwischen eh nicht unterscheiden.

*)

f([a,b,c,d], [d,c,b,a]) # => ???
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist offline   Mit Zitat antworten
Alt 05.09.2011, 02:28  
Neuer Benutzer
 
Registriert seit: 05.03.2011
Beiträge: 16
PHP-Kenntnisse:
Fortgeschritten
laszlokorte befindet sich auf einem aufstrebenden Ast
Standard

Ok, ich verstehe was du meinst, aber bei deinem Beispiel wäre eine der Lösung, dass man mindestens 3 Elemente wegen muss. Das könnt man einfach dort lassen wo es ist, weil sich dafür ja automatisch eine neue Position ergibt. Ich wäre da also mit einem Ergebnis von [a,b,c] total zu frieden und ob es nun [a,b,c] oder [a,b,d] wäre mir letztendlich noch egal.

Bei längeren Arrays (~700 Elemente) sollte das Ergebnis natürlich genauer sein.

Um dem ganzen mal etwas mehr Bezug zur Realität zu verleihen:

Ich habe eine Baum-Struktur (Kategorien und Unterkategorien mit beliebiger Tiefe und auf unterste Ebene Items, also wie so eine Forumkategorien/Threads-Struktur). Die Daten liegen aber nicht wirklich in einer rekursiven Baumstruktur vor, sondern als einfache Liste von Objekten:
Code:
[
{name:'Kategorie 1', 'deep': 0},
  {name:'Kategorie 1.1', 'deep': 1},
    {name:'Thread 1', 'deep': 2},
    {name:'Thread 2', 'deep': 2},
{name:'Kategorie 2', 'deep': 0},
{name:'Kategorie 3', 'deep': 0},
  {name:'Thread 3', 'deep': 1}
]
Diese Threads und Kategorien können nun hin und her geschoben werden. Kategorie 3 könnte in Kategorie1 oder in Kategorie1.2 verschoben werden, oder Thread 2 könnte nach oben geschoben werden, sodass er vor Thread 1 steht.

Ich will jetzt also sehen können:
- Welcher Thread und welche Kategorie wurde seit dem 1.9.2011 erstellt?
- Welche Threads wurden seit dem gelöscht?
- Welche Threads wurden verschoben? Von wo? Wohin?

Der Diff wäre nicht sehr brauchbar, wenn er mir die ganzen Kategorien und Threads als gelöscht und neu erstellt anzeigen würde, nur weil ich Thread3 an den Anfang von Kategorie1.1 verschiebe.
laszlokorte ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[Erledigt] Cannot use object of type mysqli_result as array Mynoriem PHP Einsteiger 5 18.07.2011 16:20
Feed in Datenbank eintragen (Formate: json, php serialized, xml) high_five Datenbanken 5 17.06.2010 03:04
[Erledigt] Problem bei update mit array feldern fulltilt PHP Tipps 2010 6 13.02.2010 00:59
PHPLot von der Datenbank zum mehrdimensionalen Array mannimammut PHP Tipps 2009 1 15.12.2009 10:40
[Erledigt] Tabellen die sich selbst referenzieren Squall PHP Tipps 2009 19 04.08.2009 21:33
Object as Array micbur PHP Tipps 2008 10 04.08.2009 09:46
[Erledigt] array sortieren PHP Tipps 2004 17 13.05.2009 10:44
XAMP gehts, auf realer server nicht: Fehler: Cannot use object of type ... as array mysteryxxx PHP-Fortgeschrittene 4 03.08.2008 18:08
Soapfault: Undefined Property Argi PHP-Fortgeschrittene 0 28.07.2008 11:17
Menü mit Unterpunkten supertramp Beitragsarchiv 7 18.10.2005 22:40
Problem beim vergleichen von 2 Arrays PHP Tipps 2005-2 1 06.10.2005 14:25
Sortieren von Arrays mit mehr als 2 Dimensionen (Teil 2) Buhmann PHP-Fortgeschrittene 4 12.07.2005 14:03
[Erledigt] Mehrdimensionales Array in eindimensionales Array umwandeln PHP-Fortgeschrittene 3 03.01.2005 22:31
Abfrage mit id aus anderer Tabelle suter PHP Tipps 2004-2 15 16.12.2004 14:25

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php diff object, javascript json object kleinstes gemeinsames, un diff array mit php, php diff, object $array php, php diff objects, array dif, array diff objects, diff zwei xml dateien vergleichen php, php array diff, php diff array modified, php boject array, array diff php, php xml diff

Alle Zeitangaben in WEZ +2. Es ist jetzt 11:29 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum