javascript - JS:将新对象推送到嵌套数组对象中
问题描述
我想构建一个嵌套的 JS 对象,其中包含一个数组、对象、数组等,它将homie
变量保持在不同的级别,非常类似于一个简单的存储结构,可以从 homie v3.0.1约定中存储和检索。(我在 JS 对象和数组中包含了一些我自己的结构,以提高代码的可读性和灵活性,例如以 _ 下划线开头的变量分组,因此它与 homie 约定不同。)
要存储的嵌套数组/对象的结构(在 Node-RED 全局上下文中 - 以 JS 对象格式),我称之为homie Shadow
,(大致deviceID > nodeID > propertyID > propAttribute
,其中设备、节点、属性都是嵌套对象的数组)are
,:
[
{"deviceID":
{"_nodesArr":
[
{
"nodeID":{
"_propArr":[
{"propertyID":{"_propertyAttributes":
{"$attribute: attributeValue}}}
} } ] } } ]
]
下面是一个示例数据集,它存储在 Node-RED 中名为homieShw(homie Shadow 的缩写)的全局上下文变量中:
[
{"ESP70":
{"_nodesArr":
[
{"Light": {
"_propArr":
[
{"Switch":{
"val":1,
"_propAttributes":{"$settable":true}
} } ] } } ]
]
现在,转到我想做的事情,以及我的问题:Javascript 代码将接收来自 的消息mqtt
,以设置上述结构,但也会更新变量,例如,当这个 ESP 的灯关闭时,mqtt消息如下所示:
homie/ESP70/Light/Switch/1
在不需要引用我所做的所有代码的情况下,我有一个特定的问题——那就是在homie Shadow
or 变量的数组层次结构中存储到一个数组中arrHomieShw
(从全局上下文变量中检索homieShw
)。
- 要在对象的第一个数组中添加 ESP 设备,JS 代码会测试 deviceID 是否已经在数组中,如果没有,则向数组中添加一个新元素(此代码完美运行),来自
mqtt message
上面的传入:
function checkDeviceArrCreated(deviceID, arrHomieShw){
for (i=0; i < arrHomieShw.length; i++) {
if(deviceID !== Object.keys(arrHomieShw[i])[0] ) {
foundDeviceID = 0 } else { foundDeviceID = 1; break }
}
if(foundDeviceID === 0){
branch = {[deviceID]:{ "_deviceAttributes": { "$homie": $homie } }};
arrHomieShw.push( branch );
}
}
- 上面的函数检查对象是否退出,如果没有,则将新分支推送到 arrHomieShw 中,这非常有效。
但是现在,我想对层次结构下一层的数组做同样的事情
homieShw
。因此,我想写入对象的节点数组,方法是检查 deviceID 的 nodeID 是否存在,如果不存在,则将新分支推入其中。push 命令不想像上面解释的那样推入层次结构。这是我尝试过的,(除其他外)。该函数
checkNodesArrCreated()
被调用,例如使用这个 mqtt 消息 :homie/ESP70/Air/Temperature/23
,在变量之后arrIdxDevice = getDeviceIdx();
- 请参见下面的这个函数。在函数
checkNodesArrCreated()
中,被推送到嵌套数组中的分支变量arrHomieShw
创建了一个新对象,并且不会在它找到的同一设备 ID 下分支。我还尝试使用 arrHomieShw.deviceID.push(branch) 的变体,但这也不起作用。
我该怎么办?
//-----------------------------------------------------------------------
function checkNodesArrCreated(){
if(deviceID == Object.keys(arrHomieShw[arrIdxDevice])[0] ) {
theObj = Object.values(arrHomieShw[arrIdxDevice][deviceID])
if(theObj._nodesArr === undefined){
branch = { _nodesArr:
{[nodeID]:{"_nodeAttributes": { [nodeAttribute]: val } } }
};
arrHomieShw.push( branch );
}
}
}
//-----------------------------------------------------------------------
function getDeviceIdx(){
for (i=0; i < arrHomieShw.length; i++) {
if(deviceID == Object.keys(arrHomieShw[i])[0] ) {
return i;
}
}
return arrIdxDevice;
}
function getNodeIdx(deviceID, nodeID, arrIdxDevice, arrHomieShw){
for (j=0; j < arrHomieShw[arrIdxDevice][deviceID]._nodesArr.length; j++) {
if(nodeID == arrHomieShw[arrIdxDevice][deviceID]._nodesArr[j]){
return j;
}
}
}
解决方案
推荐阅读
- plc - 通过引用传递的输入变量的语义是什么?
- excel - Excel VBA:是否有可用于日期的动态数组?
- css - 如何将 CSS 动画导出为动画 PNG、gif 或 WEBP *具有透明度*?
- javascript - 阻止用户调用 io() 从控制台创建新的套接字连接
- node.js - 推荐模式通过 API 响应分页直到用尽?
- java - 接受字符串输入到数组中并检查数组中字符串的可用性
- swift - 如何在 Swift 中将自动锁定设置为从不?
- java - 当我使用处理程序时,SetContentView 不起作用
- ios - 使用 Crypto Swift 进行 iOS 13 AES 解密不起作用
- android - 在 Android 上构建二维码扫描应用