Sprawne przeformatowanie obiektu JSON

Sprawne przeformatowanie obiektu JSON
Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
0

Chciałbym sprawnie – czytaj: łatwo i szybko – przeformatować obiekt JSON, zapisany w pliku tekstowym. Przykład – załóżmy, że obiekt wygląda tak:

Kopiuj
{
    "A": [ { "B": "B1" }, ... ],
    "C": "D",
    "E": [ {
            "F": "G",
            "H": [ { "I": 1, "J": 2 }, ... ]
        },
        ...
    ]
}

I chciałbym przeformatować go na przykład tak:

Kopiuj
{
    "A": [ { "B": { "I": 1, "J": 2 } }, ... ],
    "C": "D",
    "E": [ {
            "F": "G",
            "H": [ "B1", ... ]
        },
        ...
    ]
}

Jak widać, nie doszła żadna nowa treść, jedynie części wartości właściwości A oraz H uległy zamianie miejscami. I, powiedzmy, to byłaby jedyna zamiana w tym pliku, ale oczywiście – te wartości zmieniłyby się dla wielu elementów powyższych tablic. Gdyby wielokropki oznaczały maksymalnie nawet 5 elementów, to jeszcze można by to sformatować ręcznie. Ale jeśli mogą oznaczać 10 i 20 obiektów (tj. 10 * 20 elementów łącznie do wyszukania, zaznaczenia i zmiany miejscami, z prawdopodbieństwem pomyłki), to rozważam użycie np. skryptu. Obecnie jeszcze nie wiem, jak będę potrzebował pozamieniać wartości miejscami, będę musiał nad tym pomyśleć głębiej.

Pytanie: jak to zrobić, jakim językiem, może narzędziem? Może nie ma możliwości zrobienia tego szybciej niż ręcznie?


edytowany 3x, ostatnio: Silv
DE
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 3 lata
  • Postów:50
1

Nie wiem, co masz na myśli ręcznie. Ale powinno się dać napisać skrypt, który Ci skonwertuje obiekty. Co prawda, przy każdej zmianie, musiałaś byś taki skrypt pisać praktycznie od nowa.
Wydaje mi się, że nie ma żadnych uniwersalnych narzędzi do takich zadań specjalnych. Ale może się mylę.

Zamieszczam przykład w JS:

Kopiuj
const objectInFile = { // twój przykładowy obiekt
    "A": [ { "B": "B1" }, { "B": "B2" } ],
    "C": "D",
    "E": [ {
            "F": "G",
            "H": [ { "I": 1, "J": 2 }, { "K": 3, "L": 4 }, 
                   { "M": 5, "N": 6} 
                 ]
        },
    ]
}

//funkcja która skonwertuje obiekt 
function convertObject(obj){
  const result = Object.assign({}, objectInFile);
  result.A = [];
  result.E = [];
  obj.E.forEach((value, i) => {
    const h = [];
    value.H.forEach((value, i) => {
      result.A.push({B: value});
      h.push("B"+ (i || ''));
    })
    result.E.push({F: "G", H:h});
  })
  
  return result;
}
const newObj = convertObject(objectInFile);
console.log(newObj);


//w wyniku dostaniemy taki obiekt
{
  "A": [
    { "B": { "I": 1, "J": 2 } },
    { "B": { "K": 3, "L": 4 } },
    { "B": { "M": 5, "N": 6 } }
  ],
  "C": "D",
  "E": [{ "F": "G", "H": ["B", "B1", "B2"] }]
}

https://jscomplete.com/playground/s267059

Silv
Dzięki! Może się przyda. Że też Ci się chciało...
Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
0

Może doprecyzuję, co już ustaliłem (aczkolwiek chyba nie ma sensu, bo coś czuję, że i tak nici z tego większej automatyzacji): najprawdopodobniej dane będą właśnie zamieniane miejscami między właściwościami/elementami o tych samych nazwach i poziomach. Czyli, na przykład, wartość właściwości X z poziomu zagnieżdżenia 3 zamienia miejsce z wartością właściwości Y z poziomu zagnieżdżenia 2, i tak co drugi element poziomu zagnieżdżenia 1, przez, powiedzmy, 50 poziomów.

PS. Właściwość X nazywa się tak samo – X – na każdym poziomie, podobnie właściwość Y.


edytowany 4x, ostatnio: Silv
Freja Draco
Freja Draco
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:3394
0

Nie wnikałam specjalnie, więc może coś mi umyka, ale czy najprościej nie byłoby użyć standardowych funkcji?

  • JSON.parse - zrobić z tego jsona obiekt js,
  • przeprowadzić odpowiednie operacje na właściwościach stworzonego nią obiektu,
  • JSON.stringify - ze zmodyfikowanego obiektu wygenerować nowego jsona.

Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
0

@Freja Draco: no zgadzam się, niemniej właśnie punkt nr 2 jest najbardziej problematyczny. :)


  • Rejestracja:około 6 lat
  • Ostatnio:ponad rok
2
Kopiuj
> jq -c . <in.json
{"A":[{"B":"B1"}],"C":"D","E":[{"F":"G","H":[{"I":1,"J":2}]}]}
> 
> jq -c '.A as $A | .A = .E[].H | .E[].H = $A' <in.json
{"A":[{"I":1,"J":2}],"C":"D","E":[{"F":"G","H":[{"B":"B1"}]}]}
> 

Możliwe, że da się to zrobić lepiej (parallel assignment?). Składnię jq zapominam po 5 minutach.

Silv
Wydaje się ciekawe i dość bliskie temu, co chciałbym osiągnąć.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.