summaryrefslogtreecommitdiff
path: root/src/array.js
blob: c53113e55a2a9872d3b9c7eb71e31d46361520da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// Extend the array class to expose update
// functionality, plus provide some
// useful helper methods
export default function(graffiti) {

  return class GraffitiArray extends Array {

    get mine() {
      return this.filter(o=> o._by==graffiti.myID)
    }

    get notMine() {
      return this.filter(o=> o._by!=graffiti.myID)
    }

    get authors() {
      return [...new Set(this.map(o=> o._by))]
    }

    async removeMine() {
      await Promise.all(
        this.mine.map(async o=> await o._remove()))
    }

    #getProperty(obj, propertyPath) {
      // Split it up by periods
      propertyPath = propertyPath.match(/([^\.]+)/g)
      // Traverse down the path tree
      for (const property of propertyPath) {
        obj = obj[property]
      }
      return obj
    }

    sortBy(propertyPath) {

      const sortOrder = propertyPath[0] == '-'? -1 : 1
      if (sortOrder < 0) propertyPath = propertyPath.substring(1)

      return this.sort((a, b)=> {
        const propertyA = this.#getProperty(a, propertyPath)
        const propertyB = this.#getProperty(b, propertyPath)
        return sortOrder * (
          propertyA < propertyB? -1 : 
          propertyA > propertyB?  1 : 0 )
      })
    }

    groupBy(propertyPath) {
      return this.reduce((chain, obj)=> {
        const property = this.#getProperty(obj, propertyPath)
        if (property in chain) {
          chain[property].push(obj)
        } else {
          chain[property] = new GraffitiArray(obj)
        }
        return chain
      }, {})
    }

  }
}