首页 > 解决方案 > Javascript 检查年份范围是否与其他范围冲突

问题描述

所以,我有一个代表年份的两个整数的对象,如下所示:

const targetRange = { from: 2015, to: 2020 };

然后我有一个具有其他范围的数组,如下所示:

const currentRanges = [
    { from: 2003, to: 2006 },
    { from: 2006, to: 2010 },
    { from: 2010, to: 2014 },
    { from: 2014, to: 2019 },
]

我想创建一个函数rangesCollide来检查目标范围是否与任何当前范围发生冲突。

例子:

rangesCollide({ from: 2010, to: 2015 }, { from: 2007, to: 2010 }); // false
rangesCollide({ from: 2010, to: 2015 }, { from: 2007, to: 2011 }); // true
rangesCollide({ from: 2010, to: 2015 }, { from: 2010, to: 2010 }); // false
rangesCollide({ from: 2010, to: 2015 }, { from: 2010, to: 2013 }); // true
rangesCollide({ from: 2010, to: 2015 }, { from: 2011, to: 2014 }); // true
rangesCollide({ from: 2010, to: 2015 }, { from: 2015, to: 2015 }); // false
rangesCollide({ from: 2010, to: 2015 }, { from: 2014, to: 2018 }); // true
rangesCollide({ from: 2010, to: 2015 }, { from: 2015, to: 2020 }); // false
rangesCollide({ from: 2010, to: 2015 }, { from: 2018, to: 2022 }); // false

我无法想象如何让它发挥作用。

好的,我发现了这个:

找出两条线段是否相交

这基本上是相同的问题,这是解决方案:

function overlap(A1,A2,B1,B2) {
    return A1<=B1?A2>=B1:B2>=A1;
}

但我不得不将 <= 和 >= 分别更改为 < 和 >。

标签: javascript

解决方案


这里有两件事,首先你要检查一个值是否存在于数组中。[array.prototype.some 方法][1] 非常适合这个。第二个是范围是否冲突。

some 方法将一个函数作为参数,并将每个数组索引的值传递给该函数,一旦返回 true 就结束,直到它检查了数组中的每个值。

话虽如此,我们不能编写碰撞检查函数来接受两个参数,因为它不能与 . 一起使用some,而是我们使用 curried 函数,一个返回函数的函数。我们用目标值调用第一部分,some然后调用第二部分,直到找到匹配项,或者检查数组中的每个值。

我在代码中添加了更多目标范围,以测试碰撞逻辑是否按预期工作。

const targetRange1 = { from: 2015, to: 2020 }
const targetRange2 = { from: 2000, to: 2022 }
const targetRange3 = { from: 2000, to: 2001 }
const targetRange4 = { from: 2020, to: 2021 }
const targetRange5 = { from: 2000, to: 2004 }
const targetRange6 = { from: 2015, to: 2016 }

const currentRanges = [
    { from: 2003, to: 2006 },
    { from: 2006, to: 2010 },
    { from: 2010, to: 2014 },
    { from: 2014, to: 2019 },
]

const rangesCollide = (r1) => (r2) => {
  if ((r1.from > r2.from && r1.from < r2.to) || (r1.from <= r2.from && r1.to > r2.from)) {
    return true
  }
  return false
}

const check1 = currentRanges.some(rangesCollide(targetRange1))
const check2 = currentRanges.some(rangesCollide(targetRange2))
const check3 = currentRanges.some(rangesCollide(targetRange3))
const check4 = currentRanges.some(rangesCollide(targetRange4))
const check5 = currentRanges.some(rangesCollide(targetRange5))
const check6 = currentRanges.some(rangesCollide(targetRange6))

document.querySelector('.p1').innerHTML = `check1 = ${check1}`
document.querySelector('.p2').innerHTML = `check2 = ${check2}`
document.querySelector('.p3').innerHTML = `check3 = ${check3}`
document.querySelector('.p4').innerHTML = `check4 = ${check4}`
document.querySelector('.p5').innerHTML = `check5 = ${check5}`
document.querySelector('.p6').innerHTML = `check6 = ${check6}`
<p class="p1"></p>
<p class="p2"></p>
<p class="p3"></p>
<p class="p4"></p>
<p class="p5"></p>
<p class="p6"></p>



  [1]: https://developer.cdn.mozilla.net/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some

推荐阅读