使用对象通过JSON进行迭代
Iterating through JSON using an object
我正在创建一个模板选择器/轮盘Slack机器人。目标是向机器人发送消息,并像命令行一样传递参数,让它遍历JSON对象,随机选择一个符合条件的模板。用户也应该能够传递任意数量的参数。
示例:我用这个Roulette -s -i
给机器人发消息,参数是代表侧边栏的-s
和代表索引的-i
。因此,机器人需要找到一个既有侧边栏又有索引的模板。
这是我的JSON对象示例:
{
name: "foo",
index: {
hasIndex: true
},
sidebar: {
hasSidebar: true
}
}
这是我的代码:
controller.hears(["roulette", "^pattern$"],["direct_message", "direct_mention", "mention"], function(bot,message) {
const data = require('./data.js');
const nodeList = []
const args = message.text.match(/-'w/g);
const obj = {
'-s': '.sidebar.hasSidebar',
'-i': '.index.hasIndex'
}
args.forEach(function(arg) {
var path = obj[arg];
// console.log(path) when passing arguments -s or -i
// the path variable correctly gives me .sidebar.hasSidebar, etc
data.forEach(function(node) {
// console.log(node) Gives me my data set
// console.log(node.path) This is the issue, it returns undefined.
if (node.path === true) {
nodeList.push(node.name)
}
});
});
});
我的问题是,如果node
正确地为我提供了数据集,为什么我不能使用node.path
?难道我不应该添加path
并完成路径,以便forEach循环通过吗?相反,我得到了undefined
,我不明白为什么。
编辑
我已经更新了我的代码:
var nodeList = data.filter(function(node) {
return args.every(function(arg) {
return obj[arg](node);
});
});
const obj = {
'-s': function (node) { return node.sidebar.hasSidebar; },
'-i': function (node) { return node.index.hasIndex; },
};
data.forEach(function(node) {
args.forEach(function(arg) {
var pathTester = obj[arg];
if (pathTester(node)) {
nodeList.push(node.name)
}
});
});
1) 我正确地交换了循环吗?
2) 我不太明白nodeList应该如何工作。
编写时:
if (node.path === true)
您正在寻找名为path
的房产。这与您之前在上声明的变量path
无关
使用此语法无法查找基于点分隔字符串(如'.sidebar.hasSidebar'
)的动态属性链。您必须调用eval()
才能实现这一点,如下所示:
if (eval('node' + path) === true)
这是可行的,但因为eval
的名声不好,我建议用函数而不是字符串的值来定义obj
,比如:
const obj = {
'-s': function (node) { return node.sidebar.hasSidebar; },
'-i': function (node) { return node.index.hasIndex; },
};
然后检索并调用函数:
args.forEach(function(arg) {
var pathTester = obj[arg];
data.forEach(function(node) {
if (pathTester(node)) {
nodeList.push(node.name);
}
});
});
算法修正
现在,以上回答了问题,但正如您提到的:
示例:我用这个
Roulette -s -i
给机器人发消息,参数是代表侧边栏的-s
和代表索引的-i
。因此,机器人需要找到一个既有侧边栏又有索引的模板。
我需要指出的是,即使只有一个条件为真,您当前的代码也会将节点推送到节点列表中,并且相同的节点可能会被推送到它几次。
如果您希望仅在所有条件都为true时添加节点,则交换循环,并确保仅在(然后)内部循环对所有参数返回true时才添加节点。
同时,我建议使用every
和filter
功能:
var nodeList = data.filter(function(node) {
return args.every(function(arg) {
return obj[arg](node);
});
});
请注意,此将替换现有的forEach
循环。完整的代码如下所示:
controller.hears(["roulette", "^pattern$"],["direct_message", "direct_mention", "mention"], function(bot,message) {
const data = require('./data.js');
const args = message.text.match(/-'w/g);
const obj = {
'-s': function (node) { return node.sidebar.hasSidebar; },
'-i': function (node) { return node.index.hasIndex; },
};
var nodeList = data.filter(function(node) {
return args.every(function(arg) {
return obj[arg](node);
});
});
});
关于filter
和every
的更多信息
以上是取filter
和every
的幂。如果没有这些方法,代码可能看起来像这样:
var nodeList = [];
data.forEach(function(node) {
// Check if this node should be added
var addNode = true; // start positive...
args.forEach(function(arg) {
var pathTester = obj[arg];
if (pathTester(node) !== true) {
// if not all paths are true, don't add the node
addNode = false;
}
});
if (addNode) {
nodeList.push(node);
}
});
与true
相比的更多信息
当编写这样的代码时:
if (property === true)
和您确信属性始终是布尔值(如果已定义),那么您可以编写以下内容:
if (property)
这是因为if
语句需要计算为布尔值的东西。但是,如果属性已经是布尔值,则无需与true
进行比较。属性有三种可能性。要么是:
undefined
false
true
当这三个值中的一个是if
表达式时,只有最后一个true
会使if
条件成为true
。CCD_ 34被认为是一个伪值。
但是,如果属性也可以是非布尔值,如数字、字符串或对象,并且您只想响应true
的确切值(而不是任何其他值),那么您需要像=== true
一样进行测试。如果没有它,非零数值、非空字符串和对象也将通过测试。
- 如何在Jquery中迭代JSON数组
- 如何迭代json对象结构以只获取名称
- 迭代 JSON 文件并且未在 Javascript 中正确返回结果
- 如何迭代json对象的嵌套属性并创建新的数组列表
- 迭代JSON对象并将元素打印到屏幕上的最佳方式是什么
- 无法使用jquery迭代json对象
- 使用嵌入式数组迭代JSON
- 如何使用 D3 javascript 迭代 JSON 文件中的数据
- 如何解析 JSON 字符串和迭代 JSON 对象
- 如何使用Jade和Node.js迭代JSON数组
- 访问特定属性并在 AngularJS 中迭代 JSON 数组
- 如何在 jsRender 模板中迭代 JSON 数组
- 如何使用jQuery迭代json数组和拉取值
- Javascript - 递归 - 迭代 json,用户能够跳过
- 翡翠混合迭代 json
- 从 stomp 消息响应 (JavaScript) 迭代 json 数组
- 在 coffeescript 中迭代 json 响应文本
- 迭代 json 响应
- Javascript 按索引迭代 json
- 在 Angular 项目中迭代 JSON 响应以创建新的 $scope obj 我可以在应用程序中使用的