src/json-patch.js
function patchArray(original, newA, basePath) {
  let patches = [];
  const oldA = original.slice();
  let tmpIdx = -1;

  function findIndex(a, id, idx) {
    if (a[idx] && isUndef(a[idx].qInfo)) {
      return null;
    } if (a[idx] && a[idx].qInfo.qId === id) {
      // shortcut if identical
      return idx;
    }
    for (let ii = 0, ll = a.length; ii < ll; ii += 1) {
      if (a[ii] && a[ii].qInfo.qId === id) {
        return ii;
      }
    }
    return -1;
  }

  if (compare(newA, oldA)) {
    // array is unchanged
    return patches;
  }

  if (!isUndef(newA[0]) && isUndef(newA[0].qInfo)) {
    // we cannot create patches without unique identifiers, replace array...
    patches.push({
      op: 'replace',
      path: basePath,
      value: newA,
    });
    return patches;
  }

  for (let i = oldA.length - 1; i >= 0; i -= 1) {
    tmpIdx = findIndex(newA, oldA[i].qInfo && oldA[i].qInfo.qId, i);
    if (tmpIdx === -1) {
      patches.push({
        op: 'remove',
        path: `${basePath}/${i}`,
      });
      oldA.splice(i, 1);
    } else {
      patches = patches.concat(JSONPatch.generate(oldA[i], newA[tmpIdx], `${basePath}/${i}`));
    }
  }

  for (let i = 0, l = newA.length; i < l; i += 1) {
    tmpIdx = findIndex(oldA, newA[i].qInfo && newA[i].qInfo.qId);
    if (tmpIdx === -1) {
      patches.push({
        op: 'add',
        path: `${basePath}/${i}`,
        value: newA[i],
      });
      oldA.splice(i, 0, newA[i]);
    } else if (tmpIdx !== i) {
      patches.push({
        op: 'move',
        path: `${basePath}/${i}`,
        from: `${basePath}/${tmpIdx}`,
      });
      oldA.splice(i, 0, oldA.splice(tmpIdx, 1)[0]);
    }
  }
  return patches;
}
function patchArray(original, newA, basePath) {
  let patches = [];
  const oldA = original.slice();
  let tmpIdx = -1;

  function findIndex(a, id, idx) {
    if (a[idx] && isUndef(a[idx].qInfo)) {
      return null;
    } if (a[idx] && a[idx].qInfo.qId === id) {
      // shortcut if identical
      return idx;
    }
    for (let ii = 0, ll = a.length; ii < ll; ii += 1) {
      if (a[ii] && a[ii].qInfo.qId === id) {
        return ii;
      }
    }
    return -1;
  }

  if (compare(newA, oldA)) {
    // array is unchanged
    return patches;
  }

  if (!isUndef(newA[0]) && isUndef(newA[0].qInfo)) {
    // we cannot create patches without unique identifiers, replace array...
    patches.push({
      op: 'replace',
      path: basePath,
      value: newA,
    });
    return patches;
  }

  for (let i = oldA.length - 1; i >= 0; i -= 1) {
    tmpIdx = findIndex(newA, oldA[i].qInfo && oldA[i].qInfo.qId, i);
    if (tmpIdx === -1) {
      patches.push({
        op: 'remove',
        path: `${basePath}/${i}`,
      });
      oldA.splice(i, 1);
    } else {
      patches = patches.concat(JSONPatch.generate(oldA[i], newA[tmpIdx], `${basePath}/${i}`));
    }
  }

  for (let i = 0, l = newA.length; i < l; i += 1) {
    tmpIdx = findIndex(oldA, newA[i].qInfo && newA[i].qInfo.qId);
    if (tmpIdx === -1) {
      patches.push({
        op: 'add',
        path: `${basePath}/${i}`,
        value: newA[i],
      });
      oldA.splice(i, 0, newA[i]);
    } else if (tmpIdx !== i) {
      patches.push({
        op: 'move',
        path: `${basePath}/${i}`,
        from: `${basePath}/${tmpIdx}`,
      });
      oldA.splice(i, 0, oldA.splice(tmpIdx, 1)[0]);
    }
  }
  return patches;
}
function patchArray ( original , newA , basePath ) { let patches = [ ] ; const oldA = original . slice ( ) ; let tmpIdx = - 1 ; function findIndex ( a , id , idx ) { if ( a [ idx ] && isUndef ( a [ idx ] . qInfo ) ) { return null ; } if ( a [ idx ] && a [ idx ] . qInfo . qId === id ) { // shortcut if identical return idx ; } for ( let ii = 0 , ll = a . length ; ii < ll ; ii += 1 ) { if ( a [ ii ] && a [ ii ] . qInfo . qId === id ) { return ii ; } } return - 1 ; } if ( compare ( newA , oldA ) ) { // array is unchanged return patches ; } if ( ! isUndef ( newA [ 0 ] ) && isUndef ( newA [ 0 ] . qInfo ) ) { // we cannot create patches without unique identifiers, replace array... patches . push ( { op : 'replace' , path : basePath , value : newA , } ) ; return patches ; } for ( let i = oldA . length - 1 ; i >= 0 ; i -= 1 ) { tmpIdx = findIndex ( newA , oldA [ i ] . qInfo && oldA [ i ] . qInfo . qId , i ) ; if ( tmpIdx === - 1 ) { patches . push ( { op : 'remove' , path : ` ${ basePath } ${ i } ` , } ) ; oldA . splice ( i , 1 ) ; } else { patches = patches . concat ( JSONPatch . generate ( oldA [ i ] , newA [ tmpIdx ] , ` ${ basePath } ${ i } ` ) ) ; } } for ( let i = 0 , l = newA . length ; i < l ; i += 1 ) { tmpIdx = findIndex ( oldA , newA [ i ] . qInfo && newA [ i ] . qInfo . qId ) ; if ( tmpIdx === - 1 ) { patches . push ( { op : 'add' , path : ` ${ basePath } ${ i } ` , value : newA [ i ] , } ) ; oldA . splice ( i , 0 , newA [ i ] ) ; } else if ( tmpIdx !== i ) { patches . push ( { op : 'move' , path : ` ${ basePath } ${ i } ` , from : ` ${ basePath } ${ tmpIdx } ` , } ) ; oldA . splice ( i , 0 , oldA . splice ( tmpIdx , 1 ) [ 0 ] ) ; } } return patches ; }
Generates patches by comparing two arrays.

@private
@param {Array} oldA The old (original) array, which will be patched
@param {Array} newA The new array, which will be used to compare against
@returns {Array} An array of patches (if any)
Generates patches by comparing two arrays .