Given an array that contains some status string, I want to validate if the array contains at least one sleeping
status and then validate if the rest of the statuses are either ok
or sleeping
.
So a valid array is ['ok', 'sleeping', 'sleeping', 'ok']
and an invalid array will be something like const states = ['ready', 'working','onBreak','sleeping', 'ok', 'sleeping']
What I have come up with so far is this:
const validArray = ['ok', 'sleeping', 'sleeping', 'ok'];
const isvalid = validArray.some( x => x === 'sleeping')
if(isValid){
const canDoStuff = validArray.some( x => !['ok','sleeping'].includes(x))
if(canDoStuff){
doStuff()
}
}
Ideally, I would like to validate that in a single loop,and not two loops.
Rather than .some
to check if there's one sleeping
item, use .includes
.
But, your other .some
isn't implementing the right logic either; doStuff
will only run if there's at least one item which doesn't match. Use .every
instead, and check that each does match:
const validate = input => ( input.includes('sleeping') && input.every(x => ['ok', 'sleeping'].includes(x)) ); console.log(validate(['ok', 'sleeping', 'sleeping', 'ok'])); console.log(validate(['ready', 'working','onBreak','sleeping', 'ok', 'sleeping']));
If you want the fastest code, use a simple for
loop:
'use strict'; function isValid( array ) { let sleeping = false; for( const item of array ) { if( item === 'sleeping' ) { sleeping = true; } else if( item !== 'ok' ) { return false; } } return sleeping; } function test( array ) { console.log( isValid(array) ? 'Valid:' : 'Invalid:', array ); } test( [ 'ok', 'sleeping', 'sleeping', 'ok' ] ); test( [ 'ready', 'working','onBreak','sleeping', 'ok', 'sleeping' ] );
This is a bit more code than the other answers suggest, but it will be faster than any of them.
In particular, the accepted answer uses two loops, not one. You don't see the loops directly because they are hidden inside the .includes()
and .every()
calls.
I don't mean this as a criticism of that code - it is very clean and simple, which I always like. But when performance counts, it can help to write old-school code that lets you combine multiple loops into one.
Of course it is always wise to benchmark when performance may matter, so I took the test that @scunliffe created (thanks!) and added a test that uses this for loop: https://jsben.ch/vrzl1
If you need to support old versions of Internet Explorer, use a numeric for
loop instead of the for-of
loop, and var
instead of let
and const
.
You can use a simple for-loop as follow:
const validate = arr => { let foundSleeping = false; for (let str of arr) { if (!["sleeping", "ok"].includes(str)) return false; if (str === "sleeping") foundSleeping = true; } return foundSleeping; }; console.log(validate(['ok', 'sleeping', 'sleeping', 'ok'])); console.log(validate(['ready', 'working','onBreak','sleeping', 'ok', 'sleeping']));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.