Вход

Просмотр полной версии : Перебрать массив


Роман Андреевич
24.04.2019, 09:18
Коллеги, доброго времени суток, в очередной раз затупил. Есть пример:



let fail = 10;
let requestsArr =[0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0,0, 0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0];



Смысл такой, выполняется функция, которая отправляет куда то запросы и получает ответы. Каждый элемент массива это ответ от сервера. 0 - это пустой ответ или ошибка, 1 - это ОК. Так вот мне нужно составить проверку, если у меня fail раз подряд пришел от сервера 0, то нужно закончить функцию.

Прошу помощи))) Как составить эту проверку. Заранее благодарю

laimas
24.04.2019, 09:22
А не проще ли суммировать в переменной ошибочные ответы?

Роман Андреевич
24.04.2019, 09:28
laimas, да в том и дело, что этот костыль нужен для того, что бы закончить выполнение функции если сервер отрубается. И ничего лучше)))) кроме того что бы придумать такую логику на коленках не получилось((((

Если я возьму просто сумму или же в принципе складирую fail в переменную или еще что-то, а потом сравню с чем нибудь, то по фэншую)))) это будет не корректно. Надо ловить именно ошибки подряд,

Если есть другой способ или идея, буду благодарен за подсказку

laimas
24.04.2019, 09:31
Надо ловить именно ошибки подряд

Что вам мешает при удачном ответе и ошибках, к примеру равным 3 подряд до этого удачного ответа, сбрасывать счетчик ошибок в ноль?

Malleys
24.04.2019, 09:56
(async () => {
var fails = 0;

for(let i = 0, len = 50; i < len; i++) {
const { answer } = await fetch("https://yesno.wtf/api").then(response => response.json(), () => ({}));
const ok = answer === "yes";

if(ok) {
fails = 0;
} else {
fails++;
}

console.log(i, ok);

if(fails === 5) break;
}
})();

Роман Андреевич
24.04.2019, 09:57
laimas, вопрос как взять несколько элементов массива подряд и проверить их значение. Последнее это не нужно.

Пока ничего лучше не придумал((( делать через рекурсию, вот пример:

t failRulle= 10;

let arr = [0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0];
let items = [];

if (arr.length > failRulle) {

check(arr, result => {

if (result) console.log('Обрываем');

});

}

function check(array, callback) {

if (!array.length) {

callback();

} else {

let item = array.shift();

if (item !== 1) {

check(array, callback);

} else {

for (let i = 0; i < array.length; i++) {

if (arr[i] === item) {

items = arr.splice(i, failRulle);

}

let fail = checkFails(items);

(fail) ? callback(true) : check(array, callback);

}

}

}

}

function checkFails(array) {

let fails = [];

array.forEach(item => {

if (item === 1) fails.push(item);

});

return (fails.length === failRulle) ? true : false;

}

но че то не очень помойму((

Роман Андреевич
24.04.2019, 10:02
Malleys, я так тоже думал, но тут нет очередности, нужно именно очередность соблюдать еще

laimas
24.04.2019, 10:09
Что-то я не понимаю. Если надо закончить выполнение функции на неудачные ответы, то какие ответы, те что были в прошлом или текущие? Если текущие, то даже при наличии массива при удачном ответе нужно инициализировать его заново, зачем хранить то, что проверять бессмысленно? А если так, то зачем вообще массив?

Malleys
24.04.2019, 10:12
Malleys, я так тоже думал, но тут нет очередности, нужно именно очередность соблюдать еще Вы лжёте! Если бы это было не так, то вы бы не читали этот ответ!

Возможно вам стоит запустить тот пример несколько раз, поскольку от того API приходят случайные Да!/Нет! и могло не быть подряд 5 Нет! Когда возникает подряд 5 Нет! то запросы обрываются!

UPD О да! Следующий запрос начинает только после завершения предыдущего!

Роман Андреевич
24.04.2019, 10:38
коллеги, спасибо. Вопрос решен. Большое всем спасибо. Задача конечно специфичная, но тем не менее.

SuperZen
24.04.2019, 14:50
console.log('result', [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
.reduce((acc, curr) => {
if (acc.count < 10) {
if (acc.prev === curr) acc.count++
else acc = {
prev: curr,
count: 1
}
}
return acc
}, {
prev: null,
count: 0,
}
).count >= 10 ? 'fail' : 'success'
)

rxjs

import { interval } from 'rxjs';
import { scan, mergeMap, takeWhile } from 'rxjs/operators';

interval(1000).pipe(
mergeMap(() => Promise.resolve(Math.round(Math.random() * 1))),
scan((acc, curr) => curr === 1 ? ++acc : 0, 0),
takeWhile(acc => {
console.log(acc)
return acc < 2
})
).subscribe()

Dilettante_Pro
24.04.2019, 15:12
Без массива: массив не имеет смысла. По текущим ответам.
i - общий счетчик запросов.
function answer() {
return Math.floor(Math.random() + 0.45);
};
var limit = 5,
fail = 0,
i = 0;
while (fail < limit) {
answer() > 0? fail = 0: fail = fail + 1;
i = i + 1;
}
alert(i);