Reputation: 33
Say I have some JSON like the following:
{
"items":
{
"item":
[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
},
...
]
}
}
I'd like a function to return a list of tab delimited data (where -> is a tab). Something like this:
items.item.length -> 1
items.item[0].id -> 0001
items.item[0].type -> donut
items.item[0].name -> Cake
items.item[0].ppu -> 0.55
items.item[0].batters.batter.length -> 4
items.item[0].batters.batter[0].id -> 1001
items.item[0].batters.batter[0].type -> Regular
items.item[0].batters.batter[1].id -> 1002
items.item[0].batters.batter[1].type -> Chocolate
items.item[0].batters.batter[2].id -> 1003
items.item[0].batters.batter[2].type -> Blueberry
items.item[0].batters.batter[3].id -> 1004
items.item[0].batters.batter[3].type -> Devil's Food
items.item[0].topping.length -> 7
items.item[0].topping[0].id -> 5001
items.item[0].topping[0].type -> None
items.item[0].topping[0].id -> 5002
items.item[0].topping[0].type -> Glazed
...
I'm thinking of something like
function json2txt(obj) {
var txt = '';
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if ("object" == typeof(obj[key])) {
json2txt(obj[key]);
} else txt += obj + '\t' + obj[key] + '\r';
}
}
}
"Oops! Your edit couldn't be submitted because:
Your post does not have much context to explain the code sections; please explain your scenario more clearly."
This is pretty frustrating too.
Upvotes: 3
Views: 14471
Reputation: 21
Patrick did a nice job. Here is a somewhat simpler version, tested with jsc on OSX 10.6.8:
function json2txt(obj)
{
var txt = '';
var recurse = function(_obj) {
if ('object' != typeof(_obj)) {
txt += ' = ' + _obj + '\n';
}
else {
for (var key in _obj) {
if (_obj.hasOwnProperty(key)) {
txt += '.' + key;
recurse(_obj[key]);
}
}
}
};
recurse(obj);
return txt;
}
var obj = JSON.parse(arguments[0]);
print(json2txt(obj));
Upvotes: 2
Reputation: 8054
You're on the right track with the recursive function. You'll need to add an argument to that function, though—it needs to know the path to the current point in the object.
Also, use \n
, not \r
.
var inputObject = {
items: {
foo: [ 'apples', 'oranges', 'peaches' ],
bar: 'baz',
spam: 'eggs'
}
};
function json2txt(obj, path)
{
var txt = '';
for (var key in obj)
{
if (obj.hasOwnProperty(key))
{
if ('object' == typeof(obj[key]))
{
txt += json2txt(obj[key], path + (path ? '.' : '') + key);
}
else
{
txt += path + '.' + key + '\t' + obj[key] + '\n';
}
}
}
return txt;
}
json2txt(inputObject, '');
Fun problem!
For your example data, my code gives:
items.item.0.id 0001
items.item.0.type donut
items.item.0.name Cake
items.item.0.ppu 0.55
items.item.0.batters.batter.0.id 1001
items.item.0.batters.batter.0.type Regular
items.item.0.batters.batter.1.id 1002
items.item.0.batters.batter.1.type Chocolate
items.item.0.batters.batter.2.id 1003
items.item.0.batters.batter.2.type Blueberry
items.item.0.batters.batter.3.id 1004
items.item.0.batters.batter.3.type Devil's Food
items.item.0.topping.0.id 5001
items.item.0.topping.0.type None
items.item.0.topping.1.id 5002
items.item.0.topping.1.type Glazed
items.item.0.topping.2.id 5005
items.item.0.topping.2.type Sugar
items.item.0.topping.3.id 5007
items.item.0.topping.3.type Powdered Sugar
items.item.0.topping.4.id 5006
items.item.0.topping.4.type Chocolate with Sprinkles
items.item.0.topping.5.id 5003
items.item.0.topping.5.type Chocolate
items.item.0.topping.6.id 5004
items.item.0.topping.6.type Maple
Upvotes: 6