代码之家  ›  专栏  ›  技术社区  ›  Lance Pollard

在JavaScript中对数组进行扩散时,如何实现数组/对象路径被*移动*时的检查和忽略?

  •  0
  • Lance Pollard  · 技术社区  · 4 年前

    我见过 flitbit/diff 但上面说:

    对数组的更改被简单地记录下来。我们最关心的是结构的形状;因此,我们不会花时间来确定对象是否从阵列中的一个插槽移动到另一个插槽。。。。

    所以在那里不起作用。

    你将如何实现这一点?看起来很难。有没有可能构建一个现有的库来忽略数组 ? 或者,您将如何从零开始直接实现它?

    我的用例是,我想跟踪对JSON对象所做的所有更改,以便人们为他们所做的每一个更改获得积分/报酬。但我不想给点,如果人们只是删除一个数组路径,然后在UI中的不同位置重新添加它,那将是欺骗:)

    我开始想 路径,然后在路径上使用正则表达式,但这似乎不起作用:

    const flat = require('flat')
    
    const compute = (_a, _b) => {
      const a = flat(_a)
      const b = flat(_b)
    
      let r_a = []
      for (let k_a in a) {
        r_a.push([
          k_a,
          new RegExp(`^` + k_a.replace(/\./g, '\\.').replace(/\d+/g, '\\d+') + `$`)
        ])
      }
    
      let r_b = []
      for (let k_b in b) {
        r_b.push([
          k_b,
          new RegExp(`^` + k_b.replace(/\./g, '\\.').replace(/\d+/g, '\\d+') + `$`)
        ])
      }
    
      let diff = []
      for (let i = 0, n = r_a.length; i < n; i++) {
        let [k_a, r_a_i] = r_a[i]
        let matches = false
        k_b_loop:
        for (let k_b in b) {
          if (r_a_i.test(k_b) && a[k_a] === b[k_b]) {
            matches = true
            break k_b_loop
          }
        }
        if (!matches) {
          diff.push({
            type: 'remove',
            path: k_a
          })
        }
      }
    
      for (let i = 0, n = r_b.length; i < n; i++) {
        let [k_b, r_b_i] = r_b[i]
        let matches = false
        k_a_loop:
        for (let k_a in a) {
          if (r_b_i.test(k_a) && b[k_b] === a[k_a]) {
            matches = true
            break k_a_loop
          }
        }
        if (!matches) {
          diff.push({
            type: 'create',
            path: k_b
          })
        }
      }
    
      return diff
    }
    
    const test1 = () => {
      const a = { 
        a: [
          { a: 1, b: 2 },
          { a: 1, b: 3 }
        ],
        b: 1,
        c: 2
      }
      const b = { 
        a: [
          { a: 1, b: 3 },
          { a: 1, b: 1 },
          { a: 1, b: 4 }
        ],
        c: 3
      }
      const diff = computeDiff(a, b)
      console.log(diff)
    }
    
    test1()
    
    0 回复  |  直到 4 年前