summaryrefslogtreecommitdiff
path: root/src/array.js
blob: f0c251fc82e58e4094c2362d71bd555c283691b2 (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
63
64
// Extend the array class to expose update
// functionality, plus provide some
// useful helper methods
export default class GraffitiArray extends Array {

  constructor(graffiti, ...elements) {
    super(...elements)
    this.graffiti = graffiti
  }

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

  get notMine() {
    return this.filter(o=> o._by!=this.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(this.graffiti, obj)
      }
      return chain
    }, {})
  }

}