diff src/layout/Layout.ts @ 120:a7519d92dbc6

refactor addToValues, multiColumnSort
author drewp@bigasterisk.com
date Sun, 20 Mar 2022 13:33:51 -0700
parents 8715633f5213
children 3584f24becf4
line wrap: on
line diff
--- a/src/layout/Layout.ts	Sun Mar 20 01:17:35 2022 -0700
+++ b/src/layout/Layout.ts	Sun Mar 20 13:33:51 2022 -0700
@@ -37,6 +37,53 @@
   sections: (AlignedTable | FreeStatements)[];
 }
 
+function addToValues<K, V>(
+  imap: Immutable.Map<K, V[]>,
+  key: K,
+  newValue: V
+): Immutable.Map<K, V[]> {
+  let cur = imap.get(key, undefined);
+  let ret = imap;
+  if (cur === undefined) {
+    cur = [];
+    ret = imap.set(key, cur);
+  }
+  cur.push(newValue);
+  return ret;
+}
+
+function multiColumnSort<T>(
+  elems: T[],
+  makeSortCols: (elem: T, index: number) => Array<number | string>
+): T[] {
+  const tagged = elems.map((p, i) => {
+    return {
+      sort: makeSortCols(p, i),
+      val: p,
+    };
+  });
+  tagged.sort((e1, e2) => {
+    let index = 0;
+    for (let k1 of e1.sort) {
+      const k2 = e2.sort[index];
+      if (!Immutable.is(k1, k2)) {
+        if (typeof k1 === "number") {
+          if (typeof k2 === "number") {
+            return k1 - k2;
+          } else {
+            throw new Error(`${k1} vs ${k2}`);
+          }
+        } else {
+          return k1.localeCompare(k2 as string);
+        }
+      }
+      index++;
+    }
+    return 0;
+  });
+  return tagged.map((e) => e.val);
+}
+
 class AlignedTableBuilder {
   subjSet: UriSet = Immutable.Set();
   predSet: UriSet = Immutable.Set();
@@ -75,53 +122,38 @@
     cur.push(rdfType);
   }
 
-  private trackSubjs(subj: NamedNode, pred: NamedNode<string>) {
-    let cur = this.subjsSeenWithPred.get(pred, undefined);
-    if (cur === undefined) {
-      cur = [];
-      this.subjsSeenWithPred = this.subjsSeenWithPred.set(pred, cur);
-    }
-    cur.push(subj);
+  private trackTypes(unaliasedSubj: NamedNode<string>, rdfType: NamedNode) {
+    this.typesSeenForSubj = addToValues(
+      this.typesSeenForSubj,
+      unaliasedSubj,
+      rdfType
+    );
+  }
+
+  private trackSubjs(unaliasedSubj: NamedNode, pred: NamedNode<string>) {
+    this.subjsSeenWithPred = addToValues(
+      this.subjsSeenWithPred,
+      pred,
+      unaliasedSubj
+    );
   }
 
   _displayedPreds(): NamedNode[] {
     let preds = uniqueSortedTerms(this.predSet);
     preds = preds.filter((p) => {
-      return !p.equals(rdf.type);
-    });
-    const tagged = preds.map((p, i) => {
-      const types = this.typesSeenWithPred(p);
-      return {
-        sort: [
-          p.equals(rdfs.label) ? 0 : 1,
-          types.length == 1 ? 0 : 1,
-          types[0].equals(this.primaryType) ? 0 : 1,
-          types[0],
-          i,
-        ],
-        val: p,
-      };
+      if (p.equals(rdf.type)) return false;
+      return true;
     });
-    tagged.sort((a, b) => {
-      let ib = 0;
-      for (let k1 of a.sort) {
-        const k2 = b.sort[ib];
-        if (!Immutable.is(k1, k2)) {
-          if (typeof k1 === "number") {
-            if (typeof k2 === "number") {
-              return k1 - k2;
-            } else {
-              throw new Error(`${k1} vs ${k2}`);
-            }
-          } else {
-            return (k1 as NamedNode).id.localeCompare((k2 as NamedNode).id);
-          }
-        }
-        ib++;
-      }
-      return 0;
+    preds = multiColumnSort(preds, (elem: NamedNode, index: number) => {
+      const types = this.typesSeenWithPred(elem);
+      return [
+        elem.equals(rdfs.label) ? 0 : 1,
+        types.length == 1 ? 0 : 1,
+        types[0].equals(this.primaryType) ? 0 : 1,
+        types[0].id,
+        index,
+      ];
     });
-    preds = tagged.map((e) => e.val);
     return preds;
   }
 
@@ -177,12 +209,7 @@
       const rdfType = q.object as NamedNode;
       tableBuilders.forEach((tb) => {
         if (tb.showsType(rdfType)) {
-          let cur = out.get(s, undefined);
-          if (cur === undefined) {
-            cur = [];
-            out = out.set(s, cur);
-          }
-          cur.push(tb);
+          out = addToValues(out, s, tb);
         }
       });
     },