Как узнать, совпадает ли массив с другим массивом, и почему при попытке узнать, являются ли они ===, первый массив изменяется на второй?
Это первый раз, когда я пытался написать какой-либо код, поэтому, пожалуйста, дайте мне перерыв, если то, что я сделал, не имеет смысла, и, пожалуйста, объясните, что происходит. Я никогда не посещал занятия или что-то еще, просто прочитал пару книг, поэтому я был бы признателен, если бы вы могли что-то объяснить. я пытаюсь сделать эту проблему (инструкции следующие);
Учитывая последовательность целых чисел как массив, определите, можно ли получить строго возрастающую последовательность, удалив не более одного элемента из массива
Итак, вот что я сделал:
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;
}
Однако мы достигли цели - мы определили, можно ли сделать строго возрастающую последовательность. Мы не модифицировали массив в процессе, поэтому владелец все еще может использовать его для своих целей (например, проверить, может ли он делать строго убывающую вещь). Есть несколько вещей, которые мы могли бы сделать по-другому, может быть, немного лучше, я оставлю их вам. Вот основной алгоритм, иди играть с ним.