获取不同大小的多个数组之间的数组差异

Get array difference between multiple arrays of different sizes

为此兜兜转转了一段时间。

例如,假设我将不同的时间段存储为这个

let timechunks1 = [["09:00", "10:00", "11:00"], ["09:00", "10:00", "11:00"], ["09:00", "10:00", "11:00", "12:00"]] 
let timechunks2 = [["09:00", "10:00", "11:00"], ["09:00", "10:00", "11:00"], ["09:00", "10:00"]]


 for (let i=0; i< timechunks.length; i++) {
 differences.push(_.difference(timechunks[0], timechunks[i]))      
}

需要提取 12:00 因为它没有出现在其他人中。我得到的最接近的是下划线 _difference 但遗憾的是它没有达到我的预期。

对于 timechunks1,我正在寻找 return “12:00” 对于 timechunks2,我正在寻找 return "11:00"

的方法

添加了另一个例子

[
["09:00", "10:00", "11:00" ,"13:00"],
["09:00", "10:00", "11:00", "13:00"], 
["09:00", "10:00", "11:00", "12:00"]
]  

return ["13:00", "12:00"]

这是一种不可变的方法

function findTimeSlot(timechunks){
    const slots = _.map(_.zip(...timechunks), _.compact);
    const maxChunk = _.max(_.map(slots, slot => slot.length));

    return _.unique(_.find(slots, (slot) => slot.length < maxChunk));
}

returns

["11:00"] for findTimeSlot(timechunks2)

["12:00"] for findTimeSlot(timechunks1)

让我们知道它是否有效。

function findUniqueTimeSlots(timechunks) {
  const hm = {};
  timechunks.flat(1).forEach(el => {
    if (hm.hasOwnProperty(el)) {
      hm[el] += 1;
    } else {
      hm[el] = 1;
    }
  });
  return Object.keys(hm).filter(key => hm[key] === 1);
}

您可以按照以下步骤实现:

  • 找到共同的时间块,_.intersection(...timechunks)
  • 迭代时间块并找出每个时间块与普通时间块的不同之处,_.difference(timechunk, commons)

以下代码段可能对您有所帮助

const timechunks1 = [
  ["09:00", "10:00", "11:00"],
  ["09:00", "10:00", "11:00"],
  ["09:00", "10:00", "11:00", "12:00"],
]
const timechunks2 = [
  ["09:00", "10:00", "11:00"],
  ["09:00", "10:00", "11:00"],
  ["09:00", "10:00"],
]
const timechunks3 = [
  ["09:00", "10:00", "11:00", "13:00"],
  ["09:00", "10:00", "11:00", "13:00"],
  ["09:00", "10:00", "11:00", "12:00"],
]

const getDifferences = (timechunks) =>
  _.chain(timechunks)
    .map((timechunk) => _.difference(timechunk, _.intersection(...timechunks)))
    .flatten()
    .uniq()
    .value()

console.log(getDifferences(timechunks1))
console.log(getDifferences(timechunks2))
console.log(getDifferences(timechunks3))
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.19/lodash.min.js"></script>

您可以在 intersectiondifferenceuniq 的实现上构建它。以下是我可能如何使用 Ramda 的版本:

const notCommon = (xs, common = xs .reduce (intersection)) => 
  uniq (xs .flatMap (x => difference (x, common)))


const timechunks1 = [["09:00", "10:00", "11:00"], ["09:00", "10:00", "11:00"], ["09:00", "10:00", "11:00", "12:00"]] 
const timechunks2 = [["09:00", "10:00", "11:00"], ["09:00", "10:00", "11:00"], ["09:00", "10:00"]]
const timechunks3 = [["09:00", "10:00", "11:00" ,"13:00"], ["09:00", "10:00", "11:00", "13:00"], ["09:00", "10:00", "11:00", "12:00"]]

console .log (notCommon (timechunks1))
console .log (notCommon (timechunks2))
console .log (notCommon (timechunks3))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js"></script>
<script> const {intersection, uniq, difference} = R                  </script>

我们通过使用 intersection 找到所有集合的共同元素这里我们 reduce 在 Ramda 的二进制版本上。其他版本可能会让您执行类似 common = intersection (xs)common = intersection (...xs) 的操作,具体取决于它们的确切 API。然后我们 flatMap 对时间块执行 difference 函数,返回 common 中未找到的值。最后我们只取该列表的 uniq 元素。

用集合论的术语来说,您正在寻找的是 symmetric difference。你可以通过取并减交来找到这个集合:

function symmetricDifference(...sets) {
    return _.difference(_.union(...sets), _.intersection(...sets));
}