[解決済み] オブジェクトのプロパティの並べ替えとJSON.stringify
質問
私のアプリケーションはオブジェクトの大きな配列を持っており、私はそれらを文字列化してディスクに保存しています。残念ながら、配列内のオブジェクトが操作され、時には置換されると、オブジェクト上のプロパティは異なる順序でリストされます (それらの作成順序?)。私が配列上で JSON.stringify() を行い、それを保存すると、diff はプロパティが異なる順序でリストされていることを示し、これは diff やマージ ツールでデータをさらにマージしようとするときに厄介です。
理想的には、文字列化を実行する前に、または文字列化操作の一部として、オブジェクトのプロパティをアルファベット順に並べ替えたいと思います。多くの場所に配列オブジェクトを操作するコードがあり、常に明示的な順序でプロパティを作成するようにこれらを変更することは困難です。
提案は最も歓迎されるでしょう!
凝縮された例です。
obj = {}; obj.name="X"; obj.os="linux";
JSON.stringify(obj);
obj = {}; obj.os="linux"; obj.name="X";
JSON.stringify(obj);
これら2つのstringifyの呼び出しの出力は異なっており、私のデータのdiffに表示されていますが、私のアプリケーションはプロパティの順序を気にしていません。オブジェクトは様々な方法で、様々な場所で構築されます。
どのように解決するのですか?
よりシンプルで現代的、かつ現在ブラウザがサポートしている方法は、単純にこれだけです。
JSON.stringify(sortMyObj, Object.keys(sortMyObj).sort());
しかし、この方法は参照されていないネストされたオブジェクトを削除し、配列内のオブジェクトには適用されません。このような出力にしたい場合は、ソートオブジェクトも平坦化する必要があります。
{"a":{"h":4,"z":3},"b":2,"c":1}
これでできるんですね。
var flattenObject = function(ob) {
var toReturn = {};
for (var i in ob) {
if (!ob.hasOwnProperty(i)) continue;
if ((typeof ob[i]) == 'object') {
var flatObject = flattenObject(ob[i]);
for (var x in flatObject) {
if (!flatObject.hasOwnProperty(x)) continue;
toReturn[i + '.' + x] = flatObject[x];
}
} else {
toReturn[i] = ob[i];
}
}
return toReturn;
};
var myFlattenedObj = flattenObject(sortMyObj);
JSON.stringify(myFlattenedObj, Object.keys(myFlattenedObj).sort());
自分で調整できるものでプログラム的に行うには、オブジェクトのプロパティ名を配列に押し込み、配列をアルファベット順にソートして、その配列(正しい順序になる)を繰り返し、その順序でオブジェクトから各値を選択する必要があります。 "hasOwnProperty"もチェックされるので、間違いなくオブジェクト自身のプロパティだけを持つことになります。以下はその例です。
var obj = {"a":1,"b":2,"c":3};
function iterateObjectAlphabetically(obj, callback) {
var arr = [],
i;
for (i in obj) {
if (obj.hasOwnProperty(i)) {
arr.push(i);
}
}
arr.sort();
for (i = 0; i < arr.length; i++) {
var key = obj[arr[i]];
//console.log( obj[arr[i]] ); //here is the sorted value
//do what you want with the object property
if (callback) {
// callback returns arguments for value, key and original object
callback(obj[arr[i]], arr[i], obj);
}
}
}
iterateObjectAlphabetically(obj, function(val, key, obj) {
//do something here
});
繰り返しますが、これはアルファベット順に反復処理することを保証するものです。
最後に、最も単純な方法として、このライブラリは、渡したJSONを再帰的にソートすることができます。 https://www.npmjs.com/package/json-stable-stringify
var stringify = require('json-stable-stringify');
var obj = { c: 8, b: [{z:6,y:5,x:4},7], a: 3 };
console.log(stringify(obj));
出力
{"a":3,"b":[{"x":4,"y":5,"z":6},7],"c":8}
関連
-
JavaScriptの関数この指摘の問題を説明
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] JavaScriptのオブジェクトが空であることをテストするにはどうすればよいですか?
-
[解決済み] JavaScriptのオブジェクトにキーが存在するかどうかをチェックする?
-
[解決済み] 2つのJavaScriptオブジェクトのプロパティを動的にマージするにはどうすればよいですか?
-
[解決済み] オブジェクトの配列を日付のプロパティでソートする方法は?
-
[解決済み】オブジェクトの配列を文字列のプロパティ値でソートする
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Vueはランニングライト形式のテキストを水平方向にスクロールする機能を実装している
-
vueにおけるv-forループオブジェクトのプロパティ
-
Vueの一般的な組み込みディレクティブの説明
-
[解決済み] テスト
-
[解決済み】エラー。Ionic使用中にモジュール '../lib/utils/unsupported.js' が見つかりませんでした。
-
[解決済み】<select>で現在選択されている<option>をJavaScriptで取得するにはどうすればよいですか?
-
nodejs unhandledPromiseRejectionWarning メッセージ
-
モジュールのビルドに失敗しました。Error: ENOENT: no such file or directory, scandir 'D:\.... \node_modules
-
jq は html ページとデータを動的に分割する。
-
[解決済み] 2つのJavaScriptオブジェクトの等質性を判断する方法は?