こんにちはフロントエンドエンジニアのまさにょんです!
今回は、JavaScriptでObjectなどのDataの変更・編集を検知する方法について解説していきます。
目次
ObjectなどのDataの変更・編集を検知する方法・Logicを作成する
ObjectなどのDataの変更・編集を検知する方法の要件定義と、SampleCodeは、次のとおりです。
要件定義
- 編集(変更)を検知して、保存ボタンの Disabledを解除するようなLogicを実装するために、ObjectなどのDataの変更を検知するLogicを作成する必要があった。
- 初期のData (initData)と、編集後のData (editData) を比較して、値の変更を検知するLogicを作成する。
ObjectなどのDataの変更・編集を検知するSampleCode
// 1. 最初の_Init_Data
const existGroupData = {
id: 1,
group_id: 1,
image_url: '',
group_description: {
title: '',
content: '',
},
group_memeber_config: {
member_num: 5,
admin_num: 1,
}
};
// 2. 編集によって、変更されている_Data
const editGroupData = {
id: 1,
group_id: 1,
image_url: '',
group_description: {
title: 'ロボ玉グループについて',
content: 'ロボ玉のファンクラブなのです!',
},
group_memeber_config: {
member_num: 7,
admin_num: 1,
}
};
// 3. まずは、再帰的に、keyListを作成する
function getAllKeys(obj) {
let keys = [];
for (let key in obj) {
keys.push(key);
if (typeof obj[key] === 'object') {
keys = keys.concat(getAllKeys(obj[key]).map(subKey => `${key}.${subKey}`));
}
}
return keys;
}
// 4. group_description や group_memeber_config のような Objectに対する、Access_Keyも含まれる。
const keyList = getAllKeys(existGroupData);
console.log('keyList', keyList);
// [ 出力結果 ]
// ['id', 'group_id', 'image_url',
// 'group_description', 'group_description.title',
// 'group_description.content', 'group_memeber_config',
// 'group_memeber_config.member_num', 'group_memeber_config.admin_num']
// 5. keyList から group_description や group_memeber_config のような Objectに対する、Access_Key は削除する
// Object同士の比較では、value_変更_Check ができない!
const filteredKeyList = [];
keyList.forEach(key => {
if (key.includes('.')) {
const splitList = key.split('.');
const mainKey = splitList[0];
const findIdx = filteredKeyList.findIndex(key => key === mainKey);
if (findIdx !== -1) {
filteredKeyList.splice(findIdx, 1);
}
}
filteredKeyList.push(key);
});
console.log('filteredKeyList', filteredKeyList);
// [ 出力結果 ]
// ['id', 'group_id', 'image_url',
// 'group_description.title', 'group_description.content',
// 'group_memeber_config.member_num', 'group_memeber_config.admin_num']
// 6. 差分を比較するために必要な Access_Key_List ができたので、それを使って、差分比較をする
for (const key of filteredKeyList) {
console.log('key', key);
const splitList = key.split('.');
if (splitList.length === 1) {
existGroupData[key] === editGroupData[key]
? console.log('same')
: console.log('diff');
} else {
existGroupData[splitList[0]][splitList[1]] === editGroupData[splitList[0]][splitList[1]]
? console.log('same')
: console.log('diff');
}
console.log('----------------------------');
}
ChatGPTに質問してみた
今回のLogicを作成するにあたり、ChatGPTを活用しました。
ChatGPTに対するプロンプトは、次のとおりです。
ChatGPTに対するプロンプト
JavaScriptで、2つの同じkeyを持つObjectの値が、一致するかどうかを調べるCodeを作成してください。
ただし、Objectの中には、Objectもあり、そのObjectの中にあるkeyに紐づいた値も再帰的に調べることができるCodeにしてください。
// [ ChatGPTに対するプロンプト ]
// JavaScriptで、2つの同じkeyを持つObjectの値が、一致するかどうかを調べるCodeを作成してください。
// ただし、Objectの中には、Objectもあり、そのObjectの中にあるkeyに紐づいた値も再帰的に調べることができるCodeにしてください。
function deepEqual(obj1, obj2) {
// 両方がオブジェクトであるかどうかをチェック
if (obj1 && obj2 && typeof obj1 === "object" && typeof obj2 === "object") {
// オブジェクトのkeyを比較
const keys1 = Object.keys(obj1);
console.log('keys1', keys1);
const keys2 = Object.keys(obj2);
console.log('keys2', keys2);
if (keys1.length !== keys2.length) {
return false;
}
// keyが同じ場合は、再帰的に値を比較
for (let key of keys1) {
if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) {
return false;
}
}
return true;
} else {
// オブジェクトでない場合、単純に値を比較
return obj1 === obj2;
}
}
const obj1 = {
a: 1,
b: {
c: 2,
d: {
e: 3
}
}
};
console.log(Object.keys(obj1));
const obj2 = {
a: 1,
b: {
c: 2,
d: {
e: 3
}
}
};
console.log(deepEqual(obj1, obj2)); // true
const obj3 = {
a: 1,
b: {
c: 2,
d: {
e: 4
}
}
};
console.log(deepEqual(obj1, obj3)); // false
JavaScript書籍 Ver. 中級-上級者向け
JavaScript書籍 Ver. 初級者向け
Twitterやってます!Follow Me!
神聖グンマー帝国の逆襲🔥
神聖グンマー帝国の科学は、世界一ぃぃぃぃぃぃ!!!!!