简单的语法检查器程序-最佳数据结构
Simple grammar checker program - optimal data structure
我想为英语创建一个简单的游戏,检查某人的句子。他们能够使用单词库中的一组固定单词来构建句子。
"银行"这个词可能是一些混乱的东西,比如:
[want, eat, I, hi, to]
然后他们会按照正确的顺序造句:
hi I want to eat.
我在英语SO上问了这个问题,因为它最初涉及语法问题——这个问题已经演变成了一个更像数据结构的问题。你可以在这个链接上阅读更多关于它的信息。我最初的想法是用一套通用的英语规则来检查句子语法,似乎很快就会变得过于复杂。建议我只使用硬编码检查进行匹配,如下所示。
在我进一步定义这些检查之前,我想知道是否有更好的数据结构/方法可以用于检查语法。
if (input === the_answer) {
msg = correct!
} else {
msg = 'Try again: ' + this.grammarRules(input, the_answer));
}
Language_System.prototype.grammarRules = function(input, answer) {
var grammar_hints = {
quest1 : {
task1 : [
'The subject, Bob, needs to be first',
'The phrase is Hello there'
]
}
};
var grammar_rules = {
quest1 : {
task1 : function (input, answer) {
var error = -1;
if (input[0] !== answer[0]) {
error = 0;
} else if (input.indexOf('hello') > input.indexOf('there')) {
error = 1;
}
return grammar_hints.quest1.task1[error];
}
}
};
return grammar_rules.Lee.quest1.task1(input, answer);
};
如果您考虑一种更具声明性的方法,会容易得多:-定义标准quest
结构-定义具有通用输入格式的标准task
结构-定义通用验证器并重用它们
您从grammar_hints
对象开始就走上了正确的道路,但实际上我会把描述一个任务的所有属性都放在同一个对象中。
建议:
var quests = [
{
name: 'Quest 1',
tasks: [
{
name: 'Task 1',
solution: 'hi I want to eat',
validators: [
validators.first('hi'),
validators.verbAfterNoun('want', 'I'),
]
}
],
},
];
您将能够在多个任务中重用许多验证器,因此您希望它们尽可能通用,这里有一个例子:
var validators = {
first: function (input, term) {
if (input[0] !== term) {
return 'The sentence needs to start with: ' + term;
}
},
verbAfterNoun: function (input, verb, noun) {
if (input.indexOf(verb) < input.indexOf(noun)) {
return 'The verb, ' + verb + ', needs to come after the noun ' + noun;
}
}
};
现在,因为您想要一个声明性格式(我实际使用它们的输入初始化验证器,并将结果传递到validators
数组中),所以我们需要一个验证器工厂,它接受一个通用验证器,并返回一个仅可用于输入的助手方法。这将帮助我们,这样我们的测试框架就不需要知道有多少输入要传递给每个验证器回调
// This is a factory method that applies the given callback (with the given arguments)
function makeValidator (fn) {
return function inputFN () {
var args = [].slice.call(arguments);
return function validate (input) {
return fn.apply(null, [input].concat(args));
}
}
}
// Apply the makeValidator() method on all the validators
for (var key in validators) {
validators[key] = makeValidator(validators[key]);
}
最后,我们还想要一种根据输入检查任务的标准方法:
// This method provides the generic validation framework for any task given any input
function validate (task, input) {
var wordList = input.split(' ');
if (input === task.solution) return {success: true, errors: []};
var errors = [];
task.validators.forEach(function (fn) {
var error = fn(wordList);
if (error) errors.push(error);
});
return {success: false, errors: errors};
}
还有一些例子:
var task = quests[0].tasks[0];
console.log(validate(task, 'hi I want to eat'));
console.log(validate(task, 'I want to eat hi'));
console.log(validate(task, 'hi want I to eat'));
console.log(validate(task, 'want I to eat hi'));
综合起来:
// This is a factory method that applies the given callback (with the given arguments)
function makeValidator (fn) {
return function inputFN () {
var args = [].slice.call(arguments);
return function validate (input) {
return fn.apply(null, [input].concat(args));
}
}
}
var validators = {
first: function (input, term) {
if (input[0] !== term) {
return 'The sentence needs to start with: ' + term;
}
},
verbAfterNoun: function (input, verb, noun) {
if (input.indexOf(verb) < input.indexOf(noun)) {
return 'The verb, ' + verb + ', needs to come after the noun ' + noun;
}
}
};
// Apply the makeValidator() method on all the validators
for (var key in validators) {
validators[key] = makeValidator(validators[key]);
}
var quests = [
{
name: 'Quest 1',
tasks: [
{
name: 'Task 1',
solution: 'hi I want to eat',
validators: [
validators.first('hi'),
validators.verbAfterNoun('want', 'I'),
]
}
],
},
];
// This method provides the generic validation framework for any task given any input
function validate (task, input) {
var wordList = input.split(' ');
if (input === task.solution) return {success: true, errors: []};
var errors = [];
task.validators.forEach(function (fn) {
var error = fn(wordList);
if (error) errors.push(error);
});
return {success: false, errors: errors};
}
function printTask (input) {
var task = quests[0].tasks[0];
var result = validate(task, input);
document.body.innerHTML += '<div><b>checking:</b> ' + input + '<pre>' + JSON.stringify(result, null, 4) + '</pre><hr />';
}
// Lets look at some examples
printTask('I want to eat hi');
printTask('hi want I to eat');
printTask('want I to eat hi');
printTask('hi I want to eat');
相关文章:
- JS库支持各种数据结构?(如爪哇的番石榴)
- JavaScript数据结构
- Node JS,传统的数据结构?(如Set等),任何类似Java.util的node
- 更正扁平数据模型和noSQL数据结构
- 用于筛选无模式集合的最快数据结构
- 将数据结构转换为二进制数据
- JavaScript 设置具有对数搜索时间的数据结构
- 更好的数据结构来处理这个数组
- 应用程序的最佳目录结构 - 节点 + 道场:这行得通吗?
- Firebase 数据结构理念
- 基于其他数据结构更新 AngularJS 中的数据结构
- JavaScript - JSON 数据结构的构建 - 如何使用变量值更改键名
- 如何处理在javascript中访问数据结构的两个回调
- 文字与原型对象表示法的数据结构
- 表示可用产品的所有组合的数据结构
- Immutable.js:表示2D游戏场的数据结构
- javascript和python返回的相同数据结构在d3.js中表现不同
- JavaScript 中多项选择测验的最佳数据结构
- 关于唯一id的数据结构最佳实践's
- 简单的语法检查器程序-最佳数据结构