0

我正在处理的情况是从 JSON 对象(表示为 JavaScript 对象)中获取数据,提取一些数据并使用 JavaScript 生成新对象。新对象还将包含新添加的数据。

可以说我有以下对象:

sprite_set = {
    "frames": {
        "grass.png": {
            "frame": {
                "x": 1766,
                "y": 202
            },
            "rotated": false,
            "sourceSize": {
                "w": 128,
                "h": 128
            }
        },
        "dirt1.png": {
            "frame": {
                "x": 1766,
                "y": 202
            },
            "rotated": false,
            "sourceSize": {
                "w": 128,
                "h": 128
            }
        },
        "dirt2.png": {
            "frame": {
                "x": 2766,
                "y": 402
            },
            "rotated": false,
            "sourceSize": {
                "w": 128,
                "h": 128
            }
        }                
    }
};

从这个对象我想形成一个新的对象:

sprite_set = {
    "frames": {
        "grass": {
            "frame": {
                "x": 1766,
                "y": 202
            },
            "sourceSize": {
                "w": 128,
                "h": 128
            }
        },
        "dirt": {
            "multi_frames": {
                "frame1": {
                    "x": 1766,
                    "y": 202
                },
                "frame2": {
                    "x": 2766,
                    "y": 402
                }
             },
            "sourceSize": {
                "w": 128,
                "h": 128
            }
        }       
    }
};

所以我需要构造一个函数来获取原始对象并使用以下规则吐出新对象:

  1. 从每个“框架”中删除所有“旋转”属性
  2. 重命名“frames”中的每个子对象以删除 .png,因此“grass.png”将更改为“grass”
  3. 如果“框架”子对象名称不包含前导数字,则只需将其不变地放在新对象中
  4. 如果“帧”子对象名称确实包含前导数字,则将每个后续数字分解为父对象为“multi_frames”的新子对象

我对 JSON 真的很陌生,所以任何关于如何开始的帮助都会很棒。我不想学习,所以当我得到一些帮助时,我会解决这个问题,并在这个答案的底部不断更新我的工作方式。

还有一个问题,有没有一个 JavaScript 库可以让这个过程变得更容易?

感谢任何人的帮助。

更新

从人们评论的帮助下,这是我到目前为止:

HTML

<input type="file" id="files" name="files[]" />

* JavaScript *

var JsonObj = null;

function handleFileSelect(evt) {
    var files = evt.target.files; // FileList object
    f = files[0];
    var reader = new FileReader();

    // Closure to capture the file information.
    reader.onload = (function (theFile) {
        return function (e) {
            JsonObj = e.target.result
            console.log(JsonObj);
            var parsedJSON = JSON.parse(JsonObj);

            var oldframes = parsedJSON.frames,
                newframes = {};
            for (var framename in oldframes) {
                // var m = framename.match(/(.*)\.[^.]+$/);
                var m = framename.match(/^(.+?)(\d*)\.png$/);
                var newname = m[1];
                var frame = oldframes[framename];
                if (newname in newframes) newframes[newname].multi_frames["frame" + m[2]] = frame.frame;
                else newframes[newname] = {
                    frame: frame.frame,
                    sourcesize: frame.sourcsize
                };
                // or, if it's OK to mutate the old objects, just:
                // delete frame.rotated;
                // newframes[newname] = frame;
            }
            parsedJSON.frames = newframes;

            JsonObj = JSON.stringify(parsedJSON, null, 4)
            console.log(JsonObj);

        };
    })(f);

    // Read in JSON as a data URL.
    reader.readAsText(f, 'UTF-8');
}



document.getElementById('files').addEventListener('change', handleFileSelect, false);

我使用 HTML5 File Api 来获取 JSON 文件。我收到以下错误

Uncaught TypeError: Cannot set property 'frame2' of undefined fiddle > (anonymous function)

参考该行:

if (newname in newframes) newframes[newname].multi_frames["frame" + m[2]] = frame.frame;

我看不出问题是什么,有什么想法吗?

我在这里有一个现场 JSFiddle:http://jsfiddle.net/jamiefearon/8kUYj/48/

现在修复:这里的小提琴:http: //jsfiddle.net/jamiefearon/8kUYj/50/

4

1 回答 1

1

这应该这样做:

var oldframes = sprite_set.frames,
    newframes = {};
for (var framename in oldframes) {
    var m = framename.match(/^(.+?)(\d*)\.png$/); // not assuming it would not match
    var newname = m[1];
    var frame = oldframes[framename];
    if (! (newname in newframes)) {
        newframes[newname] = {
            sourceSize: frame.sourceSize
        };
        if (m[2])
            newframes[newname].multi_frames = {};
    }
    if (m[2])
        newframes[newname].multi_frames["frame"+m[2]] = frame.frame;
    else
        newframes[newname].frame = frame.frame;
}
sprite_set.frames = newframes;
于 2013-02-07T17:50:18.077 回答