【问题标题】:convert json to osc address and arguments将 json 转换为 osc 地址和参数
【发布时间】:2019-07-05 04:50:40
【问题描述】:

我正在尝试在 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
}

代码失败的原因是两个相同深度的嵌套对象中的第二个,去掉了其地址的第一部分,我无法理解它。 p>

我很高兴有任何想法,以及将 json 转换为 OSC 兼容格式的一般方法。

我想用node.js包osc-min使用转换发送消息。

【问题讨论】:

    标签: javascript node.js json osc


    【解决方案1】:

    如果您将之前遍历的键和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);

    【讨论】:

    • 这太棒了。这个问题我绞尽脑汁,想不通。我不是一个好的程序员:(
    • 哇,这确实解决了它!并节省了很多空间;)我不得不承认我并不完全理解那里发生的事情,但我知道我必须去了解产量和生成器功能。对于其他感兴趣的人:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…* 非常感谢@Jonas 的这个疯狂的快速和有用的回复
    • @lasse 很高兴为您提供帮助 :) (如果您了解生成器,那么理解其他非常复杂的东西会更容易,例如其他语言中的延续)
    • @TKoL 是的,生成器是 JS 中最常用的强大功能 :)(每个人都在无缘无故地使用 .reduce...)
    【解决方案2】:

    这个答案是很久以后的,但我想提供一个我真正理解的答案,因为我绝对不理解生成器的答案。

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-08
      • 2014-09-04
      • 2017-07-01
      相关资源
      最近更新 更多