Как узнать, совпадает ли массив с другим массивом, и почему при попытке узнать, являются ли они ===, первый массив изменяется на второй?

Это первый раз, когда я пытался написать какой-либо код, поэтому, пожалуйста, дайте мне перерыв, если то, что я сделал, не имеет смысла, и, пожалуйста, объясните, что происходит. Я никогда не посещал занятия или что-то еще, просто прочитал пару книг, поэтому я был бы признателен, если бы вы могли что-то объяснить. я пытаюсь сделать эту проблему (инструкции следующие);

Учитывая последовательность целых чисел как массив, определите, можно ли получить строго возрастающую последовательность, удалив не более одного элемента из массива

Итак, вот что я сделал:

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, чтобы увидеть, что происходит. это именно то, что я сделал, чтобы увидеть, что он вернул, поэтому я знал, куда идти дальше. я не прошу ответа. я не понимаю, почему он вернул то, что сделал. почему это всегда возвращает последовательность, отсортированную и сравненную (числа в порядке от наименьшего к наибольшему)? это не должно быть ответом, если только оно не возвращает "true". я ожидал, что он удалит каждый элемент массива, по одному, проверит, в порядке ли он, а затем вернет его, если нет. я выбрал {return sequence} просто чтобы посмотреть, что в итоге сделала последовательность и вернуть ее только для тех, где ответ должен быть верным. опять же, я подумал, что он проверит, была ли последовательность (в которой отсутствует последовательность элементов [x]) равна последовательности, отсортированной от большинства к наименьшему (sequence === sequence.sort(function (a,b){return a>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>b}) каждый раз? я понимаю, что это отсортировало "последовательность", а затем "последовательность" стала sequence.sort(function (a,b){return a>b}), но почему? это было внутри if заявление и должен был увидеть, были ли они ===, не делайте последовательность = к отсортированной и сравниваемой последовательности. это не так, как во втором примере, x стал y+x, что здесь происходит? почему говорят if(sequence === sequence.sort(function (a,b){return a>b})) на самом деле array.sort[compare function] последовательность, когда он только должен увидеть, равны ли они??

2 ответа

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 
    

    ... условие никогда не будет истинным, даже если исходный массив уже был отсортирован. Смотрите следующий пункт:

  • когда arr1 а также arr2 массивы, сравнивать их содержимое не так просто, как arr1 === arr2, Это просто скажет вам, являются ли они одной и той же ссылкой на объект (массив). Если они совпадают, то их содержание, следовательно, равно, но обратное неверно: если два массива являются разными ссылками, то не подразумевается, что их элементы одинаковы и в одинаковом порядке. Для этого вы должны сравнить сами элементы, что, например, вы можете сделать с every:

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

    Это было то, что вы думали, что делаете.


Обратите внимание, что задача, над которой вы работаете, была представлена ​​ранее в Stackru. См. Определение, содержит ли массив почти возрастающую последовательность

Как упоминалось в другом ответе, сравнение ссылки на массив с самим собой, конечно, вернет true,

Ваш variable это объект. Забудьте на мгновение, что это массив и прочее. К этому объекту прикреплен метод (функция), sort, Таким образом, даже если вы вызываете этот метод, объект остается прежним. Вот почему сравнение arr === arr.sort(sortMethod) вернет истину.

Теперь к проблеме под рукой. Вам нужно выяснить, существует ли более одного элемента в вашем массиве, который не больше предыдущего. Вот что-то относительно простое, есть несколько способов оптимизировать его. Но в очень простых, явных терминах (без проверки ошибок и прочего):

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;
}

Однако мы достигли цели - мы определили, можно ли сделать строго возрастающую последовательность. Мы не модифицировали массив в процессе, поэтому владелец все еще может использовать его для своих целей (например, проверить, может ли он делать строго убывающую вещь). Есть несколько вещей, которые мы могли бы сделать по-другому, может быть, немного лучше, я оставлю их вам. Вот основной алгоритм, иди играть с ним.

Другие вопросы по тегам