如何折叠两个数组,通过凹入和解开它们,但大多保持位置

How fold two arrays by concating and uniquing them but mostly keep positions

本文关键字:和解 位置 折叠 何折叠 两个 数组      更新时间:2023-09-26

我想将两个阵列折叠在一起并保留它们的位置

expect(fold([1, 2, 4], [2, 3, 4])).to.eql([1, 2, 3, 4])
expect(fold([5, 1, 17, 9, 3], [1, 17, 2, 9])).to.eql([5, 1, 17, 2, 9, 3])

我的最终目标是拥有这个

expect(diff([a, b, d, e], [b, c, d])).to.eql({
  foldedList: [a, b, c, d],
  added: [c], // elements that where in 2nd but not in 1st array
  removed: [e]  // elements that where in 1st but not in 2nd array
})

对于addedremoved的东西,有一些解决方案,但我没有发现阵列折叠的任何方法。

为你的第一个目标尝试这个

function fold(_a, _b){
  var result = [];
  for(var ind = 0, ln = Math.max(_a.length, _b.length); ind < ln; ind++){
    if (_a[ind] && result.indexOf(_a[ind]) === -1) result.push(_a[ind]);
    if (_b[ind] && result.indexOf(_b[ind]) === -1) result.push(_b[ind]);
  }
  return result;
}

我有一个稍微复杂的解决方案

function fold(arr1, arr2, sort) {
  function byOrigPositions(a, b) {
    var indexA1 = arr1.indexOf(a)
    var indexA2 = arr2.indexOf(a)
    var indexB1 = arr1.indexOf(b)
    var indexB2 = arr2.indexOf(b)
    if (indexA1 >= 0 && indexB1 >=0) {
      return indexA1 - indexB1
    }
    if (indexA2 >= 0 && indexB2 >=0) {
      return indexA2 - indexB2
    }
    if (sort) {
      return sort(a, b)
    }
    return 0
  }
  return arr2.reduce(function(res, el) {
    if (res.indexOf(el) < 0) {
      res.push(el)
    }
    return res;
  }, [].concat(arr1)).sort(byOrigPositions)
}

它在concat之后进行排序,并使用原始数组中的位置作为排序函数。作为奖励,如果位置不能以这种方式计算,您可以将排序函数作为第三个参数。

我找到了一个相当丑陋的答案,但它比我以前的答案更好:

function fold(arr1, arr2) {
  var res = [];
  var currIndex = 0
  var otherIndex = 0
  var curr = arr1
  var other = arr2
  var i = 0;
  function switchVal() {
    var tmpIndex = otherIndex
    var tmp = other
    otherIndex = currIndex
    other = curr
    curr = tmp
    currIndex = tmpIndex
  }
  do {
    var indexInOther = other.indexOf(curr[currIndex], otherIndex)
    if (indexInOther >= 0) {
      var prevItems = other.slice(otherIndex, indexInOther + 1)
      res = res.concat(prevItems)
      otherIndex = indexInOther + 1
      currIndex++
      switchVal()
    } else if (currIndex < curr.length) {
      res.push(curr[currIndex])
      currIndex++
    } else {
      switchVal()
    }
  } while(currIndex < curr.length || otherIndex < other.length)
  return res
}

它在两个数组之间切换,并尝试在另一个数组中查找当前元素。如果找到它,它会切换对两个数组的引用,并以另一种方式执行相同的操作。