我正在尝试用javascript做一个通用函数,该函数将json数据结构转换为OSC兼容格式。 OSC的意思是'/'分隔的地址字符串,分配给任何类型的参数。
像这样的嵌套json:
{
"hello":"world",
"one":{
"two":{
"three":[4, 5, 6, 7]
},
"deux":"trois",
"zwei":3
}
}
将导致:
[
{
"addr":"/hello",
"args":"world"
},
{
"addr":"/one/two/three",
"args":[4, 5, 6, 7]
},
{
"addr":"/one/deux",
"args":"trois"
},
{
"addr":"/one/zwei",
"args":3
},
]
我不喜欢递归函数,但是我认为这是唯一的方法,所以我想到了:
example = {
"hello":"world",
"one":{
"two":{
"three":[4, 5, 6, 7]
},
"deux":"trois",
"zwei":3
}
}
toOSC(example)
function toOSC(json) {
var osc_msg = [{address:""}]
createPath(json, osc_msg,0,"")
for(let o of osc_msg) {
if(o.hasOwnProperty('args')) {
console.log(o)
}
}
}
function createPath(obj, osc_msg, i, addr) {
for(let m in obj) {
osc_msg[i]['address'] += '/' + m
if(Array.isArray(obj[m]) || typeof obj[m] !== 'object') {
osc_msg[i]['args'] = obj[m]
i++
osc_msg.push({address:""})
} else {
i = createPath(obj[m], osc_msg, i, osc_msg[i].address)
i++
osc_msg.push({address:addr})
}
}
return i
}
代码失败的方式是深度相同的两个嵌套对象中的第二个对象,删除了其地址的第一部分,而我却一头雾水。 >
对于任何想法,我都很高兴,也涉及将json转换为OSC兼容格式的一般方法。
我想使用转换来通过node.js软件包osc-min发送消息。
答案 0 :(得分:2)
如果您向下遍历先前遍历的键并yield
向上推结果,则会更容易:
function* format(obj, previous = "") {
for(const [key, value] of Object.entries(obj)) {
if(typeof value !== "object" || Array.isArray(value)) {
yield { addr: previous + "/" + key, args: value };
} else {
yield* format(value, previous + "/" + key);
}
}
}
// That can be used as:
const result = [...format({ a: { b: "test", d: { e: 1 }}, c: [1, 2, 3] })];
console.log(result);
答案 1 :(得分:0)
这个答案是很久以后的了,但是我想提供一个我真正理解的答案,因为我绝对不理解生成器的答案。
function processObj(obj, path="/") {
let arr = [];
for (let key of Object.keys(obj)) {
const value = obj[key];
if(typeof value !== "object" || Array.isArray(value)) {
arr.push({
"addr": path + key,
"args": value
})
} else {
const toAdd = processObj(value, path + key + "/");
arr = arr.concat(toAdd);
}
}
return arr;
}