0

JSFiddle: http://jsfiddle.net/3WdzL/1/

ロケール JS オブジェクト ファイルをフラット化されたバージョンに変換し、元に戻す必要があります。

元のロケール オブジェクト:

var localeObj = {
    toolbar: {
        link: {
            back: 'Back',
            menu: 'Menu',
        },
        flatTest: 'something'
    },
    countries: [
        ["AF", "Afghanistan"],
        ["AX", "Åland Islands"],
        ['nested', [1, 2, 3, 4]],
        ["AL", "Albania"]
    ]
};

次の関数を使用します。

function flattenObj(obj) {
    var flattenedObj = {};

    var walk = function(obj, stringMap) {

        for(k in obj) {
            var computedKey = stringMap + (stringMap ? '.' + k : k);

            if(typeof obj[k] !== 'object') {
                flattenedObj[computedKey] = obj[k];
            } else {
                walk(obj[k], computedKey);
            }
        }
    };

    walk(obj, '');
    return flattenedObj;
}

平坦化されたオブジェクトを生成します:

{
    toolbar.link.back: Back
    toolbar.link.menu: Menu
    toolbar.flatTest: something
    countries.0.0: AF
    countries.0.1: Afghanistan
    countries.1.0: AX
    countries.1.1: Åland Islands
    countries.2.0: nested
    countries.2.1.0: 1
    countries.2.1.1: 2
    countries.2.1.2: 3
    countries.2.1.3: 4
    countries.3.0: AL
    countries.3.1: Albania 
}

次の関数を使用して元に戻すと、オブジェクトに対して正常に機能します。

function deepenObj(obj) {
  var deepenedObj = {}, tmp, parts, part;

  for (var k in obj) {
    tmp = deepenedObj;
    parts = k.split('.');

    var computedKey = parts.pop();

    while (parts.length) {
      part = parts.shift();
      tmp = tmp[part] = tmp[part] || {};
    }

    tmp[computedKey] = obj[k];
  }

  return deepenedObj;
}

しかし、配列に対して次のような構造を生成します。

region: {
    country: {
        0: {
            0: 'AF',
            1: 'Afghanistan'
        },
        ...
        2: {
            0: 'nested',
            1: {
                0: 1,
                1: 2,
                3: 4,
                4: 5
            }
        }
    }
}

明らかに、これは配列にとって望ましい結果ではなく、安全でエレガントな、または機能するソリューションをまだ考え出すことができていません。PS配列を文字列に別の方法で保存すると、変換が簡単になります。ありがとう!

4

2 に答える 2

2

オブジェクトが実際に配列であるかどうかを追跡する必要があります。

var walk = function(obj, stringMap) {
    if (Array.isArray(obj) {
        for (var k = 0; k < obj.length; k++)
            var computedKey = stringMap ? stringMap + ',' + k : k;
    } else {
        for (var k in obj) {
            var computedKey = stringMap ? stringMap + '.' + k : k;
        ...

次に、深化すると:

for (var k in obj) {
    tmp = deepenedObj;
    parts = ["."].concat(k.split(/([\.,])/));

    var computedKey = parts.pop(), sign;

    while (parts.length) {
        sign = parts.shift();
        part = !parts.length ? computedKey : parts.shift();
        tmp = tmp[part] = tmp[part] || (sign === "," ? [] : {});
    }

    tmp[computedKey] = obj[k];
}

Array.isArrayである可能性があることに注意してくださいundefined。代わりに使用できますobj instanceof Array

最初のポイント/コンマが計算されたキーに保存されないため、このソリューションlocaleObjは配列ではなくオブジェクト リテラルの場合に機能します。必要に応じて関数を変更できます。

ここでの秘訣はsplit、正規表現で使用する場合に分割された配列にキャプチャされたグループをプッシュするという異常な動作を使用することです。そのため、すべてのキー部分の前に適切な区切り文字があります。

于 2013-06-10T15:10:29.050 に答える