如何在Javascript中区分2个数组并获得最小数量的更改

时间:2016-11-28 09:05:55

标签: javascript arrays

我刚刚开始研究JSON diffing脚本,并提出了一个非常基本的解决方案。

我首先将它们压平成ES6地图

// Flattener
function flatten (obj) {
  const res = new Map()
  _flatten(null, obj, res)
  return res
}

function _flatten (key, obj, res) {
  if (typeof obj === 'object') {
    const k = key ? `${key}.` : ''
    const oKeys = Object.keys(obj)

    if (oKeys.length === 0) {
      // Handle empty object
      return res.set(key, Array.isArray(obj) ? [] : {})
    }
    else {
      return oKeys.map(x => _flatten(`${k}${x}`, obj[x], res))
    }
  }
  res.set(key, obj)
}

然后用查找函数区分它们:

function diffing (before, after) {
  const r = new Map([ ['i', []], ['u', []], ['d', []] ])
  const flatBefore = flatten(before)
  const flatAfter = flatten(after)

  flatAfter.forEach((val, key) => {
    const hasKey = flatBefore.has(key)

    if (!hasKey) {
      // Insertion
      const event = { type: 'i', key: key, value: val }
      r.set('i', r.get('i').concat(event))
    }
  })

  flatBefore.forEach((val, key) => {
    const hasKey = flatAfter.has(key)
    const hasChanged = flatAfter.get(key) !== val

    // Update
    if (hasKey) {
      if (hasChanged) {
        const event = { type: 'u', key: key, value: flatAfter.get(key) }
        r.set('u', r.get('u').concat(event))
      }
    }
    else {
      // Deletion
      const event = { type: 'd', key: key, value: val }
      r.set('d', r.get('d').concat(event))
    }
  })

  return r
}

这是我的第一次尝试。我可以获得对象键的任何插入/删除。

数组出现问题(按位置键入)。只要我在底部添加或删除元素,它就可以工作。但是如果我在开头添加一个元素,整个hashmap就会中断。

const arr1 = ['google', 'apple', 'facebook', 'amazon', 'microsoft']
const arr2 = ['uber', 'google', 'apple', 'facebook', 'amazon', 'microsoft']

Map {
  '0' => 'google',
  '1' => 'apple',
  '2' => 'facebook',
  '3' => 'amazon',
  '4' => 'microsoft' }
Map {
  '0' => 'uber',
  '1' => 'google',
  '2' => 'apple',
  '3' => 'facebook',
  '4' => 'amazon',
  '5' => 'microsoft' }
Map {
  'i' => [ { type: 'i', key: '5', value: 'microsoft' } ],
  'u' => [ { type: 'u', key: '0', value: 'uber' },
  { type: 'u', key: '1', value: 'google' },
  { type: 'u', key: '2', value: 'apple' },
  { type: 'u', key: '3', value: 'facebook' },
  { type: 'u', key: '4', value: 'amazon' } ],
  'd' => [] }

我正在寻找一个足够聪明的解决方案,实际上不会重新考虑每个职位,但会给我以下结果:

  • Uber已插入位置0

那就是它。

我不是在寻找解决方案,而是建议我如何解决这个问题,以及我是走在正确的道路上还是我完全错了。

非常感谢。

0 个答案:

没有答案