Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 分析数组并检查项目是否在开始和结束之间包装_Javascript_Algorithm - Fatal编程技术网

Javascript 分析数组并检查项目是否在开始和结束之间包装

Javascript 分析数组并检查项目是否在开始和结束之间包装,javascript,algorithm,Javascript,Algorithm,我有一系列类似这样的项目: [ { id: 1, val: 'start' }, { id: 2, val: 'xxx' }, { id: 3, val: 'yyy' }, { id: 4, val: 'end' }, { id: 5, val: 'start' }, { id: 6, val: 'zzz' }, { id: 7, val: 'end' }, { id: 8, val: 'aaa' } ] 我想确保如果有一个启动,

我有一系列类似这样的项目:

[
    { id: 1, val: 'start' },
    { id: 2, val: 'xxx' },
    { id: 3, val: 'yyy' },
    { id: 4, val: 'end' },
    { id: 5, val: 'start' },
    { id: 6, val: 'zzz' },
    { id: 7, val: 'end' },
    { id: 8, val: 'aaa' }
]

我想确保如果有一个<代码>启动<代码>,应该有一个<代码>结束>代码(另一个方法),如果有一个代码>开始/结束< /代码>耦合,中间应该有一些东西(不是开始或结束)

我考虑在数组中循环,并针对每次出现的
start
从该索引中再次循环,以找到至少一个正常项、无开始项和一个结束项

我不擅长递归,所以这将是有史以来创建的最麻烦的嵌套for循环

我考虑过将数组值展平,得到如下结果

startxxxyyyendstartzzendaaa
并提出一个正则表达式,其工作原理类似于查找html开始和结束标记。但我还是不擅长正则表达式

我还尝试使用Array.reduce()并失败


你有解决这个问题的好方法吗?

这里有一个相当简单的方法。它保留一个计数器-当找到“开始”时,它递增计数器。当找到“end”时,它会将其递减。如果计数器低于
0
,则会出现错误(额外的“结束”)。如果计数器大于1,则会出现错误(额外的“开始”)。在循环结束时,如果计数器不等于
0
,则存在错误。还有额外的代码来检查“开始”之后是否紧接着“结束”

a=[
{id:1,val:'start'},
{id:2,val:'xxx'},
{id:3,val:'yyy'},
{id:4,val:'end'},
{id:5,val:'start'},
{id:6,val:'zzz'},
{id:7,val:'end'},
{id:8,val:'aaa'}
];
让计数=0;
设last=null;
for(让e of a){
如果(e.val=='start')计数++;
否则如果(e.val=='end'){
计数--;
如果(最后一次==‘开始’)计数=-1;
}
如果(计数<0 | |计数>1)中断;
last=e.val;
}
//如果计数!=此处为0,出现错误
如果(计数!=0)console.log(“失败”);
else console.log(“已通过”);

这里有一个相当简单的方法。它保留一个计数器-当找到“开始”时,它递增计数器。当找到“end”时,它会将其递减。如果计数器低于
0
,则会出现错误(额外的“结束”)。如果计数器大于1,则会出现错误(额外的“开始”)。在循环结束时,如果计数器不等于
0
,则存在错误。还有额外的代码来检查“开始”之后是否紧接着“结束”

a=[
{id:1,val:'start'},
{id:2,val:'xxx'},
{id:3,val:'yyy'},
{id:4,val:'end'},
{id:5,val:'start'},
{id:6,val:'zzz'},
{id:7,val:'end'},
{id:8,val:'aaa'}
];
让计数=0;
设last=null;
for(让e of a){
如果(e.val=='start')计数++;
否则如果(e.val=='end'){
计数--;
如果(最后一次==‘开始’)计数=-1;
}
如果(计数<0 | |计数>1)中断;
last=e.val;
}
//如果计数!=此处为0,出现错误
如果(计数!=0)console.log(“失败”);
else console.log(“已通过”);
在状态机中思考 我们可以把这个问题看作是定义良好的机器中状态之间的转换。这是一个从初始状态
中性
开始的,只有一个接受状态(
#
),也就是
中性

在每个令牌--
'start'
'end'
或其他(
'*'
)上,我们根据所处的状态和令牌的值转换到一个状态。我们可以使用下面的函数获取初始状态、接受状态列表和转换列表,并返回一个函数,该函数获取一系列令牌,并报告在运行完所有令牌后,函数是否以接受状态之一结束

在这里,我们将各州命名为中性州,因为到目前为止,我们所看到的一切都已经平衡了<代码>打开,当我们看到
开始
令牌,但没有
结束
令牌或任何其他中间令牌时<当我们看到
开始
令牌和至少一个中间令牌(除了
开始
结束
)时,代码>已填充;以及
错误
,当我们已经到达令牌流无效的点时。我们使用状态名编写转换,并将令牌值或
*
作为通配符,允许除
开始
结束
之外的任何令牌

我们可以这样编码:

const stateMachine=(初始、接受、规则)=>(xs)=>
接受.includes(xs.reduce(
(c,x)=>(
rules.find(([s,t])=>s==c&&x==t)|///精确匹配
rules.find(([s,t])=>s==c&&t=='*')|///泛型匹配
[,c]//没有匹配,因此没有转换
) [2],
最初的
))
const myMachine=状态机('Neutral',['Neutral'][
[‘空档’、‘启动’、‘打开’],
[‘中立’、‘结束’、‘错误’],
[“中性”、“中性”、“中性”],
[“打开”、“开始”、“错误”],
[“打开”、“结束”、“错误”],
[‘打开’、‘*’、‘填充’],
[“已填充”、“开始”、“错误”],
[“填充”、“结束”、“中性”],
['Filled'、'*'、'Filled'],
['Error'、'*'、'Error'],
])
常量检查=(xs)=>
myMachine([…xs].map(({val})=>val))
常量a=[{id:1,val:'start'},{id:2,val:'xxx'},{id:3,val:'yyy'},{id:4,val:'end'},{id:5,val:'start'},{id:6,val:'zzz'},{id:7,val:'end'},{id:8,val:'aaa'}]
console.log(检查(a))
在状态机中思考 我们可以把这个问题看作是定义良好的机器中状态之间的转换。这是一个从初始状态
中性
开始的,只有一个接受状态(
#
),也就是
中性

let a = [
    { id: 1, val: 'start' },
    { id: 2, val: 'xxx' },
    { id: 3, val: 'yyy' },
    { id: 4, val: 'end' },
    { id: 5, val: 'start' },
    { id: 6, val: 'zzz' },
    { id: 7, val: 'end' },
    { id: 8, val: 'aaa' }
];

let count = 0;
let last = null;
for (let e of a) {
    if (e.val === 'start') count++;
    else if (e.val == 'end') {
        count--;
        if (last === 'start') count = -1;
    }
    if (count < 0 || count > 1) break;
    last = e.val;
}
// If count != 0 here, there was an error
if (count != 0) console.log("failed");
else console.log("passed");