Итак, я создал функцию, чтобы проверить, равны ли элементы в массиве, и если да, вернуть истину или ложь, если они не равны. И в итоге я получил:
var uni;
function isUniform(uni) {
// capture first number of array
var base = uni[0];
// check if next numbers are equal to first number
for (var i = 0; i < uni.length; i++ ) {
if (uni[i] !== base){
return false;
}
else{return true;} }
}
моя проблема заключалась в том, что независимо от того, какой массив я ввожу в функцию, он всегда будет верните истину. после некоторых экспериментов я закончил тем, что вернул true вне цикла, и, наконец, это сработало.
var uni;
function isUniform(uni) {
// capture first number of array
var base = uni[0];
// check if next numbers are equal to first number
for (var i = 0; i < uni.length; i++ ) {
if (uni[i] !== base){
return false;
}}
return true;
}
Итак, мой вопрос: почему мне нужно помещать «return true» вне цикла for, чтобы функция работала? Я думаю, что знаю причину, но мне хотелось бы, чтобы объяснение было четким.
Отсортируйте массив. Тогда, если первый и последний равны, все они должны быть равны.
@Barmar, за исключением того, что сортировка O (n log (n)) и повторение, как это, O (n). Более разумно настроить эту относительно простую логику, чем реализовать более сложную логику, которая также имеет побочный эффект сортировки входного массива, что больше не делает его чистой функцией.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Когда интерпретатор встречает return, он немедленно завершает текущую функцию - не просто текущий работающий блок. Итак, в вашем первом фрагменте первый соответствующий элемент приведет к return true - isUniform приведет к false только в том случае, если элемент каждый отличается от а также, вы начинаете сравнение со второго элемента вместо того, чтобы начинать с первого (потому что arr[0] === arr[0] всегда истинно, кроме случаев, когда arr[0] NaN или что-то подобное странное, например ссылка на геттер)
Но проще было бы написать свою функцию следующим образом:
const isUniform = (input) => {
const base = input[0];
return input.every(element => element === base);
}
console.info(isUniform([0, 1, 2]));
console.info(isUniform([0, 0, 0]));Вне цикла вы устанавливаете базу, равную первому элементу в списке. Затем вы перебираете все элементы в списке, включая первый. Следовательно, первая итерация всегда будет истинной, поскольку base = uni [0].
Предположим, у вас есть следующее:
[0,0,1]
Первые два элемента одинаковы, что приведет к выполнению return true. return завершает функцию и, следовательно, цикл, и, следовательно, последнюю запись (которая отличается) никогда даже не сравнивается!
Убедитесь сами, как следующий цикл выполняется только один раз:
const loop = function () {
for(let i=1; i<100000; i++) {
console.info("I looped " + i + " time")
return true
}
}
loop()Если вы имеете дело только с числами, вы можете попробовать следующее:
function allNumbersEqual (arr) {
return Math.min(...arr) === Math.max(...arr);
}
console.info(allNumbersEqual([0.1, 0.1, 0.1, 0.1, 0.1, 0.1]));
// true
console.info(allNumbersEqual([0.1, 0.2, 0.3, 1, 2, 3]));
// false
Зачем делать это за O (n), если вы можете сделать это за O (n * 2)? : D
В вашем первом фрагменте говорится: «Если 0-й элемент соответствует 0-му элементу, то все элементы равны».