19

私は次のようなオブジェクトを持っています

{ "status": "success", "auth": { "code": "23123213", "name": "qwerty asdfgh" } }

次のようなドット表記(1レベル)バージョンに変換したい:

{ "status": "success", "auth.code": "23123213", "auth.name": "qwerty asdfgh" }

現在、フィールドを使用してオブジェクトを手動で変換していますが、これを行うには、より適切で一般的な方法があるはずです。ありますか?

注:反対の方法を示す例がいくつかありますが、正確な方法が見つかりませんでした。

注2:サーバーサイドコントローラーのアクションバインディングで使用したい。

4

7 に答える 7

37

プロパティを新しいオブジェクトに再帰的に追加してから、JSONに変換できます。

var res = {};
(function recurse(obj, current) {
  for(var key in obj) {
    var value = obj[key];
    var newKey = (current ? current + "." + key : key);  // joined key with dot
    if(value && typeof value === "object") {
      recurse(value, newKey);  // it's a nested object, so do it again
    } else {
      res[newKey] = value;  // it's not an object, so set the property
    }
  }
})(obj);
var result = JSON.stringify(res);  // convert result to JSON
于 2012-11-04T13:16:06.137 に答える
10

undefinedこれは、最初のプレフィックスを取得するときの修正/ハックです。(やった)

var dotize = dotize || {};

dotize.parse = function(jsonobj, prefix) {
  var newobj = {};
  function recurse(o, p) {
    for (var f in o)
    {
      var pre = (p === undefined ? '' : p + ".");
      if (o[f] && typeof o[f] === "object"){
        newobj = recurse(o[f], pre + f);
      } else {
        newobj[pre + f] = o[f];
      }
    }
    return newobj;
  }
  return recurse(jsonobj, prefix);
};
于 2013-09-02T21:21:39.200 に答える
5

NPMドットオブジェクトGithub)を使用して、オブジェクトからドットへの変換、またはその逆を行うことができます。

于 2019-03-18T18:23:00.360 に答える
1

プレフィックス機能を備えた別の関数を作成しました。コードを実行できませんでしたが、答えは得られました。ありがとう

https://github.com/vardars/dotize

var dotize = dotize || {};

dotize.convert = function(jsonobj, prefix) {
    var newobj = {};

    function recurse(o, p, isArrayItem) {
        for (var f in o) {
            if (o[f] && typeof o[f] === "object") {
                if (Array.isArray(o[f]))
                    newobj = recurse(o[f], (p ? p + "." : "") + f, true); // array
                else {
                    if (isArrayItem)
                        newobj = recurse(o[f], (p ? p : "") + "[" + f + "]"); // array item object
                    else
                        newobj = recurse(o[f], (p ? p + "." : "") + f); // object
                }
            } else {
                if (isArrayItem)
                    newobj[p + "[" + f + "]"] = o[f]; // array item primitive
                else
                    newobj[p + "." + f] = o[f]; // primitive
            }
        }
        return newobj;
    }

    return recurse(jsonobj, prefix);
};
于 2012-11-04T13:24:36.343 に答える
1

const sourceObj = { "status": "success", "auth": { "code": "23123213", "name": "qwerty asdfgh" } }
;

const { auth, ...newObj } = sourceObj;

const resultObj = {
  ...newObj,
  ..._.mapKeys(auth, (val, key) => `auth.${key}`)
}


// function approach
const dotizeField = (obj, key) => {
  const { ...newObj } = sourceObj;

  delete newObj[key];

  return {
    ...newObj,
    ..._.mapKeys(obj[key], (val, subKey) => `${key}.${subKey}`)
  }
}

const resultObj2 = dotizeField(sourceObj, 'auth');

console.log(sourceObj, resultObj, resultObj2);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.20/lodash.min.js"></script>

于 2021-01-12T13:01:54.477 に答える
1

@pimvdbが行ったこと(彼が提出したコンパクトで効果的なソリューション)に続いて、簡単にエクスポートできる関数を使用できるようにするための小さな変更を追加しました。

    function changeObjectToDotNotationFormat(inputObject, current, prefinalObject) {
      const result = prefinalObject ? prefinalObject : {}; // This allows us to use the most recent result object in the recursive call
      for (let key in inputObject) {
        let value = inputObject[key];
        let newKey = current ? `${current}.${key}` : key;
        if (value && typeof value === "object") {
          changeObjectToDotNotationFormat(value, newKey, result);
        } else {
          result[newKey] = value;
        }
      }
      return result;
    }
于 2021-03-29T11:11:52.540 に答える
0

これはもっとエレガントだと思います...

const toDotNot = (input, parentKey) => Object.keys(input || {}).reduce((acc, key) => {
  const value = input[key];
  const outputKey = parentKey ? `${parentKey}.${key}` : `${key}`;

  // NOTE: remove `&& (!Array.isArray(value) || value.length)` to exclude empty arrays from the output
  if (value && typeof value === 'object' && (!Array.isArray(value) || value.length)) return ({ ...acc, ...toDotNot(value, outputKey) });

  return ({ ...acc, [outputKey]: value });
}, {});

const input = {a: {b: 'c', e: {f: ['g', null, {g: 'h'}]}}, d: []};
const output = toDotNot(input);

console.log(output);

結果:

// output:
{
    "a.b": "c",
    "a.e.f.0": "g",
    "a.e.f.1": null,
    "a.e.f.2.g": "h",
    "d": []
}
于 2021-12-11T12:36:55.363 に答える