从Object中的JSON Parse Object获取值;动态密钥(JavaScript)

时间:2017-06-25 17:16:37

标签: javascript arrays json object

虽然如果我通过括号表示法指定键,我能够正确解析此有效负载,但您如何动态解析它?

{
    "name": "Demo User",
    "birthday": "January 1st",
    "hobbies": 
        {
        "morning": "coding",
        "afternoon": "kewl kids stuff",
        "nighttime": "random"
    },
    "date": "June 25th"
}

我的意思是,爱好可能不存在,或者其他领域如“最喜欢的食物”和#39;可能存在,可能是数组或对象。

这种情况在过去几个月引起了很多挫折,我试图看看是否有人能够向我解释如何动态地解析它。

我找到了一个递归的步行'这种方法不再是错误的,但它会在每次迭代时返回它遇到的第一件事。

var data = require("./demo.json");

//data = JSON.stringify(data);

function walk(obj) {
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      var val = obj[key];
      console.log(val);
      walk(val);
    }
  }
}

walk(data);

基于我发现的东西,数据被导入为JSON,如果我将其字符串化,它就会变成一个字符串(显然)。

默认

{ name: 'Demo User',
  birthday: 'January 1st',
  hobbies:
   { morning: 'coding',
     afternoon: 'kewl kids stuff',
     nighttime: 'random' },
  date: 'June 25th' }

字符串化

{"name":"Demo User","birthday":"January 1st","hobbies":{"morning":"coding","afternoon":"kewl kids stuff","nighttime":"random"},"date":"June 25th"}

两者都相似,但输出的唯一区别是垃圾邮件D X次(作为第一个值,我正在思考?)或垃圾邮件{ X次(成为第一个)字符串的值?

我尝试过更基本的

方法
var data = require("./demo.json");

for (var key in data){
    console.log(key + ':' + data[key]);
}

哪种方法很好,但正如预期的那样,爱好正在返回[object Object],因为我没有迭代它。我可以通过hobbies,但又一次 - 我不知道它是否会存在。

欢迎任何输入 - 一般性问题,但这个过程在过去几个月里让我对不同项目感到很沮丧。

更新

我的模糊性正确地引起了混乱。

我们的目标是将此JSON Payload转换为CSV格式。我需要标头的每个键,并且每个值都是所述标题下的一行。 我的问题是,当我迭代它时,我最终得到了正确转换的最高级别对象。然后我得到一个没有数据的对象Object列。

对于这个确切的例子,让我们说我的目标是将JSON转换为

name, birthday, hobbies/morning, hobbies/afternoon, hobbies/nighttime, data
Demo User, January 1st, coding, kewl kids stuff, random, June 25th

更新#2

其他array变体。

我希望

{
...
    "hobbies": 
        {
        "morning": "coding",
        "afternoon": "kewl kids stuff",
        "nighttime": "random"
    },
    ...
}

输出 hobbies/morning, hobbies/afternoon, hobbies/nighttimes

我希望

{
...
    "hobbies": ["coding", "kewl kids stuff", "coding"]
    ...
}

输出一列 hobbies引用括号的项目 "coding, kewl kids stuff, coding"

3 个答案:

答案 0 :(得分:1)

您可以检查每个值的类型并确定您要执行的操作,

var data = require("./demo.json");

walk(obj){
    for (var key in data){
        if(type(data[key]) === "string"){
            console.log(key + ':' + data[key]);
        }
        else if(Array.isArray(data[key])){
            //its an array
        }
        else if(type(data[key]) === "object"){
            //its an object
            walk(data[key])       
        }
    }
}

您的walk函数使用D{向您发送垃圾邮件的原因是因为当它加密字符串时它会进行无限循环,

function walk(obj) {
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      var val = obj[key];
      console.log(val);
      //here you need to check if it is an array or object, only then you should call walk
      //calling walk on string would send it on a infinite loop
      if(typeof(val) === "object"){
          walk(val);
      }
    }
  }
}

答案 1 :(得分:1)

尝试使用此功能(答案末尾的代码段)

/**
 * 
 * @param {object} input 
 * @returns {Array<string>}
 */
function translateObject(input) {
    if (typeof input === "object" && input !== null) {
        if (input instanceof Array) {
            var result = '"';
            for (var index in input) {
                if (index) result += ", ";
                result += input[index];
            }
            return [result + '"'];
        } else {
            var data = "", result = "";
            for (var key in input) {
                if (key.includes(",")) {
                    throw new Error("Key cannot have a comma");
                }
                var val = translateObject(input[key]);
                if (val.length === 2) {
                    var titles = val[0].split(", ");
                    var textIndex = 0;
                    var size = 0;
                    for (var index in titles) {
                        var title = titles[index];
                        var titleVal = val[1].substring(textIndex, textIndex + title.length);
                        if (result) { result += ", "; data += ", "; }
                        textIndex += title.length + 2;
                        title = key + "/" + title;
                        size = Math.max(title.length, titleVal.length);
                        result += title + " ".repeat(size - title.length);
                        data += titleVal + " ".repeat(size - titleVal.length);
                    }
                } else if (val.length === 1) {
                    size = Math.max(val[0].length, key.length);
                    if (result) { result += ", "; data += ", "; }
                    result += key + " ".repeat(size - key.length);
                    data += val[0] + " ".repeat(size - val[0].length);
                }
            }
            return [result, data];
        }
    }
    return [input];
}

这是一个有效的例子:

var object = {
    "a": "1",
    "b": "2",
    "c":
    {
        "e": "3",
        "f": "4",
        "g": "5"
    },
    "d": "6"
};

function translateObject(input) {
    if (typeof input === "object" && input !== null) {
        if (input instanceof Array) {
            var result = '"';
            for (var index in input) {
                if (index) result += ", ";
                result += input[index];
            }
            return [result + '"'];
        } else {
            var data = "", result = "";
            for (var key in input) {
                if (key.includes(",")) {
                    throw new Error("Key cannot have a comma");
                }
                var val = translateObject(input[key]);
                if (val.length === 2) {
                    var titles = val[0].split(", ");
                    var textIndex = 0;
                    var size = 0;
                    for (var index in titles) {
                        var title = titles[index];
                        var titleVal = val[1].substring(textIndex, textIndex + title.length);
                        if (result) { result += ", "; data += ", "; }
                        textIndex += title.length + 2;
                        title = key + "/" + title;
                        size = Math.max(title.length, titleVal.length);
                        result += title + " ".repeat(size - title.length);
                        data += titleVal + " ".repeat(size - titleVal.length);
                    }
                } else if (val.length === 1) {
                    size = Math.max(val[0].length, key.length);
                    if (result) { result += ", "; data += ", "; }
                    result += key + " ".repeat(size - key.length);
                    data += val[0] + " ".repeat(size - val[0].length);
                }
            }
            return [result, data];
        }
    }
    return [input];
}

function objectToCsv(object) {
    var result = translateObject(object);
    return result[0] + "\n" + result[1];
}

var csv = objectToCsv(object);
document.querySelector("#console").innerText = csv;
console.log(csv);
#console {
  font-family: Courier New,Courier,Lucida Sans Typewriter,Lucida Typewriter,monospace;
  white-space: pre;
}

span {
  color: darkgrey;
}
<div id="console"></div>
<span>Names were minified to fit result in one line so that it is easier to read</span>
<span>Use this font family if you want all characters to have the same width</span>

答案 2 :(得分:0)

您所描述的可能是您所期望的对象的一个​​或多个属性不存在,或者没有内容(或成员,如果它是一个数组),以及如何在此基础上构建代码的情况。

它不能完全随机,否则你不会谈论csv样式输出。所以我会假设你的对象内容大部分存在,但有时你会发现缺少的东西。

如果是我的话,我会预先处理你使用JSON.parse()或你用来将字符串转换为javascript对象的等效物时加载的对象。我会使用jquery的$.extend之类的东西将完美形成的对象合并到我的数据中,而array merging则将目标作为数组属性。这将为我提供一致的数据模型来编码。

总而言之 - 您必须按照您希望的方式制作数据,以便能够毫无意外地使用它。