JavaScriptでObjectなどのDataの変更・編集を検知する方法・Logicを作成する

JavaScript_diff_Check

こんにちはフロントエンドエンジニアのまさにょんです!

今回は、JavaScriptでObjectなどのDataの変更・編集を検知する方法について解説していきます。

ObjectなどのDataの変更・編集を検知する方法・Logicを作成する

ObjectなどのDataの変更・編集を検知する方法の要件定義と、SampleCodeは、次のとおりです。

要件定義

  1. 編集(変更)を検知して、保存ボタンの Disabledを解除するようなLogicを実装するために、ObjectなどのDataの変更を検知するLogicを作成する必要があった。
  2. 初期の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!

神聖グンマー帝国の逆襲🔥

神聖グンマー帝国の科学は、世界一ぃぃぃぃぃぃ!!!!!

最近の投稿