【问题标题】:How do I see if an array is the same as another array & why does trying to see if they are === change the first array into the second array?如何查看一个数组是否与另一个数组相同以及为什么尝试查看它们是否 === 将第一个数组更改为第二个数组?
【发布时间】:2018-02-01 23:38:19
【问题描述】:

这是我第一次尝试编写任何代码,所以如果我所做的没有意义,请让我休息一下,并请解释发生了什么。我从来没有上过课或任何东西,只是读了几本书,所以如果你能解释一下,我将不胜感激。我正在尝试解决这个问题(说明如下);

给定一个整数序列作为一个数组,判断是否有可能通过从数组中删除不超过一个元素来获得一个严格递增的序列

所以,这就是我所做的:

function almostIncreasingSequence (sequence) {
  for(x=0; x < sequence.length; x++) {
    var y = sequence[x];
    sequence.splice[x,1];
    if (sequence === sequence.sort(function (a, b) {return a > b})) {
      return sequence
    } else {
      sequence.splice[x,0,"y"]
    }
  }
}  

当我将 true 和 false 作为返回它们应该去的地方时,它没有返回我想要的东西,所以我用序列替换了 true 并删除了 false 以查看发生了什么。这正是我所做的,看看它返回了什么,所以我知道从那里去哪里。我不是在问答案。我很困惑为什么它会返回它所做的事情。为什么这总是返回排序和比较的序列(数字从最小到最大)?这不应该是答案,除非它应该返回“真”。我所期望的是它会删除数组的每个元素,一次一个,检查它是否有序,如果没有,则将其放回原处。我选择{return sequence} 只是为了看看这个序列最终做了什么,并且只为了答案应该是真的而返回它。再一次,我想它会检查序列(现在缺少元素序列[x])是否等于从最大到最小排序的序列(sequence === sequence.sort(function (a,b){return a&gt;b})),如果是,则返回'true',或者替换数组[ x] 如果没有。然后重新开始,但它每次只返回从最少到最多的数组。为什么不隔离第四行?它不只是查看它们是否彼此相等,而是服从命令并更改整个序列定义。就像我要写:

function almostIncreasingSequence (sequence) {
  for (x=0; x < sequence.length; x++) {
    var y = 1;
    var x = 3;
    if(x === y + x) {
      return x
    } else {
      return y
    }
  }
}

这不会返回y+x,它总是返回y,那么为什么第一个示例每次都返回sequence.sort(function (a,b){return a&gt;b})?我意识到它对“序列”进行了排序,然后“序列”变成了sequence.sort(function (a,b){return a&gt;b}),但为什么呢?它在if 语句中,应该查看它们是否是===,而不是使序列= 成为排序和比较的序列。它不像,在第二个例子中,x 变成了y+x。这是怎么回事?为什么说if(sequence === sequence.sort(function (a,b){return a&gt;b}))实际上是array.sort[compare function]序列,而它只是应该看看它们是否相等?

【问题讨论】:

  • 欢迎来到 Stack Overflow。还请访问help center 并在可能的情况下阅读How to Ask,以便您知道将来要做什么。
  • @Patrick Roberts 谢谢

标签: javascript arrays sorting comparable array-splice


【解决方案1】:

sort 方法返回与您应用sort 方法相同的数组对象,而不是(排序的)数组。数组本身已排序,因此原始顺序丢失。这称为就地排序。所以x.sort() === x对于任何数组x总是为真,与它的排序方式无关。比较是在对象(数组)引用上进行的,并且该引用在排序期间不会改变。

所以有两个问题同时发生:

  • sort 改变它被调用的数组。如果您想获得数组的排序版本而不影响原始数组,那么您必须先复制一份,例如slice

    sequence.slice().sort((a, b) => a - b)
    

    现在sequence 不会被排序,但表达式将返回它的排序副本。如果你想这样继续:

    const sortedSeq = sequence.slice().sort((a,b) => a - b);
    if (sequence === sortedSeq[i]) then // ...etc 
    

    ...条件将从不为真,即使原始数组已经排序。看下一点:

  • arr1arr2是数组时,比较它们的内容并不像arr1 === arr2那么简单。这只会告诉你它们是否是同一个对象(数组)引用。如果它们是,那么它们的内容因此是相等的,但反之则不然:如果两个数组是不同的引用,那么并不意味着它们的元素相同且顺序相同。为此,您必须比较元素本身,例如您可以使用every

    const sortedSeq = sequence.slice().sort((a,b) => a - b);
    if (sequence.every( (a, i) => a === sortedSeq[i] ) then // ...etc 
    

    是你以为你在做的。


请注意,您正在处理的挑战之前已在 StackOverflow 上提出过。见Determine whether array holds an almost increasing sequence

【讨论】:

  • 我试图解释,但它说它太长了。我把它分成以下几个
  • 对,我知道我到处都是,所以看起来你不明白我的问题。我会尝试更好地澄清。另外,我查看了所有其他问题,他们没有说我在问什么。正如我所说,我不是在寻找问题的答案,而是在寻找关于为什么它返回排序数组以及如何查看数组是否相同的问题的答案(就像在相同的每个元素中一样) array[#]) 作为排序数组而不是等于它。我不明白为什么它每次都返回一个排序序列。
  • 据我所知,我从来没有真正对它进行过排序;我只是想看看这个序列是否等于一个排序的序列,但它不应该是,所以它应该被替换并返回到开头。如果答案应该是假的,据我所知,这段代码将返回 null。它显然没有,但我想了解它为什么返回它所做的。我知道x.sort() === x 但通过询问if(x.sort() === x) 它实际上对x 进行了排序。为什么?这是我放入2, 4, 11, 1, 6, 8 的数组,它返回了1, 4, 6, 8, 11,它应该只是返回数组,而不是排序的数组。
  • 这就是我提到第二个示例的原因,因为它不会将 if 语句作为执行的命令返回。它没有将x 更改为y+x,但第一个将array 更改为array.sort()。另外,如果我们使用 words 或仅使用 numbersx.sort() === x 会是真的吗?
  • 我知道数字是相等的,因为 unicode,但是字母或单词呢?我不明白为什么它取出sequence[x] 然后返回排序后的数组,即使我写了return sequence。为什么它不返回原始序列减去sequence[x],而不是像它那样返回排序后减去sequence[x] 的序列?我不希望它对数组进行排序,只需将数组与排序后的数组进行比较。然后如果它们相等,则返回原始数组
【解决方案2】:

正如另一个答案中提到的,将数组的引用与其自身进行比较当然会返回true

您的variable 是一个对象。暂时忘记它是一个数组和东西。该对象附加了一个方法(函数)sort。所以即使你调用那个方法,对象还是一样的。这就是为什么比较 arr === arr.sort(sortMethod) 会返回 true。

现在,解决手头的问题。您需要查找数组中是否有多个元素不大于之前的元素。这是一个比较简单的东西,有几种方法可以优化它。但用非常简单、明确的术语(没有错误检查和其他东西):

function isAlmostIncreasing(sequence) {
  // Hold a reference to our joker card
  let joker = false;
  // Start counting from the second array element (index = 1).
  for (let i = 1; i < sequence.length; i++) {
    // compare previous and current elements:
    const current = sequence[i];
    const previous = sequence[i - 1];
    if (!(current > previous) {
      // uh-oh! current integer is not bigger than the previous one!
      if (!joker) {
        // Phew! We can use our joker!
        joker = true;
      } else {
        // Oh, darn. Joker is used up, this is now the second bad element.
        // We might as well give up and let people know this is not a good sequence.
        return false;
      }
    }
  }
  // Well, if we are here, it means we're good, right?
  return true;
}

不过,我们实现了目标 - 我们确定是否可以创建严格递增的序列。在这个过程中我们没有修改数组,所以所有者仍然可以将它用于他们的目的(例如检查他是否可以做严格递减的事情)。我们可以做一些不同的事情,也许更好一点,我会把它们留给你。这是一个基本算法,去玩吧。

【讨论】:

  • 谢谢,我想我明白为什么它们是相等的,但直到那个解释我才明白,但我仍然不明白为什么它返回一个排序的序列,即使我要求它只返回序列。它是如何排序的?或者为什么?我试图在 cmets 中向其他人更好地解释它
  • 您有没有打电话给sort?可能是副作用。
猜你喜欢
  • 1970-01-01
  • 2018-08-30
  • 2021-11-06
  • 2023-03-23
  • 2021-03-03
  • 1970-01-01
  • 1970-01-01
  • 2017-05-30
  • 1970-01-01
相关资源
最近更新 更多