In the process of writing a package that will import `Roam Research` JSON dumps into `org-roam`, I try to parse the large JSON dump.
This JSON dump is a representation of all the notes taken with Roam Research. As you might know, Roam Research is an outliner mainly, and each line of text is an outline element, which is represented as a nested (json) structure in the dump file.
Now I am able to read the json dump and get a lisp-datastructure that represents the json data. The lisp datastructure that represents it consists of vectors of alists. Example:
;; Vector holding "nodes" or lists of alists
[ ;; First element of the vector. Or: First node so to speak:
(
(create-time . 1629555623149)
(title . "August 16th, 2021")
(:create/user
(:user/uid . "DELETEDDELETEDDELETED"))
(:log/id . 1629555623145)
(children . [...])
(uid . "08-16-2021")
(edit-time . 1629883978909)
(:edit/user (:user/uid . "DELETEDDELETEDDELETED")
...
As you can see, the lisp representation consists of a (top level) vector holding alists with keys-and-values.
To get the data out of this structure I need to walk through this nested datastructure. So I'd like to write a recursive function that looks at the current (head) element of this list, analyse it, get the relevant data out of it and see if there are child-elements (which are again vectors of alists).
Now comes the recursive part: My code will look at the child elements, and if there are any, then call the recursive function on the child node, and if there are no child elements, take the rest of the initial list and apply my recursive function to the vector with the removed first element.
## Question
1. How can I remove the first element from a vector? Could not find anything on the net.
2. Are there idiomatic ways in Elisp to walk a nested structure?
3. Is recursion too slow to parse a 10mb large json structure?
## Code fragments for reading / parsing the JSON
This code snippet allows me to read a json dump and return a lisp data structure that represents the json dump:
(require 'json)
(defvar *roam-graph-json-dump-filename*
"~/.emacs.d/lisp/process-roam-json/roam-research.json"
"Will hold the filename of the Roam Research json dump.")
(defvar *roam-json-alist*
(ugt-read-roam-json)
"Read Roam Research JSON dump, save resulting vector of alists in a var.")
;; https://emacs.stackexchange.com/questions/34331/how-do-you-get-data-by-key-from-a-json-list
(defun ugt-read-roam-json nil
(interactive)
(let* ((filepath *roam-graph-json-dump-filename*)
;; `json-read-file'
;; returns a vector (list in Python lingo.)
;; of association lists.
(json (json-read-file filepath)))
json))
The raw JSON data starts like this:
[
{
"create-time": 1629113623149,
"title": "August 16th, 2021",
":create/user": { ":user/uid": "DELETEDDELETEDDELETED" },
":log/id": 1629113623145,
"children": [
{
"edit-time": 1632126970878,
"children": [
{
"string": "Montag",
"create-time": 1632126263419,
"heading": 2,
":create/user": { ":user/uid": "DELETEDDELETEDDELETED" },
"uid": "2dE80Sh8T",
"edit-time": 1632126267229,
":edit/user": { ":user/uid": "DELETEDDELETEDDELETED" }
},
{
...
The lisp datastructure that represents it, consists of vectors of alists. Example:
;; Vector holding "nodes" or lists of alists
[ ;; First element of the vector. Or: First node so to speak:
(
(create-time . 1629555623149)
(title . "August 16th, 2021")
(:create/user
(:user/uid . "DELETEDDELETEDDELETED"))
(:log/id . 1629555623145)
(children . [...])
(uid . "08-16-2021")
(edit-time . 1629883978909)
(:edit/user (:user/uid . "DELETEDDELETEDDELETED")
...