如何匹配两个JSON文件中的id字段并更新源JSON(Node.js命令行工具场景)
Hey Rachel, let's get that update functionality working smoothly! You were right to think about array methods like reduce() and map()—they're perfect for this job. Here's a straightforward way to match IDs, replace old entries with updated ones, and keep your code clean:
Step-by-Step Explanation
1. First, Create an ID-to-Update Mapping
For efficiency (especially if you have lots of playlists or update entries), we'll convert the payload array from your update action into an object where each key is a playlist ID, and the value is the updated playlist data. We'll use reduce() for this:
const updateMap = actionDetail.payload.reduce((acc, updatedItem) => { acc[updatedItem.id] = updatedItem; return acc; }, {});
This lets us look up any updated playlist by ID in O(1) time, instead of looping through the payload every time we check a source entry.
2. Replace Matching Entries in the Source Data
Next, we'll use map() to iterate over the source playlists. For each entry:
- If its ID exists in our
updateMap, we'll use the updated version - If not, we'll keep the original entry
This replaces the old entry with the new one in a single pass—no need to delete and push separately!
data[table] = data[table].map(item => { return updateMap[item.id] || item; });
Full Updated Code for the Update Branch
Here's how your update block will look when integrated into your existing code:
if(actionDetail.action === 'update') { console.log('This is an UPDATE entry'); // Create a map of update IDs to their new data const updateMap = actionDetail.payload.reduce((acc, updatedItem) => { acc[updatedItem.id] = updatedItem; return acc; }, {}); // Replace matching entries in the source data data[table] = data[table].map(item => updateMap[item.id] || item); }
Full Working Code
Here's the complete script with the update functionality added:
const fs = require('fs'); const inputFile = 'source.json'; // Keep dynamic if needed const changesFile = 'changes.json'; // Load source file const data = JSON.parse(fs.readFileSync('./' + inputFile)); // Load changes file const changes = JSON.parse(fs.readFileSync('./' + changesFile)); for(const [table, actions] of Object.entries(changes)) { console.log(`Processing table: ${table}`); if(!(table in data)) continue; // Iterate through CRUD directives for(const actionDetail of actions) { if(actionDetail.action === 'create') { console.log('This is a CREATE entry'); data[table].push(...actionDetail.payload); } if(actionDetail.action === 'delete') { console.log('This is a DELETE entry'); // Future delete logic example: // const deleteIds = actionDetail.payload.map(item => item.id); // data[table] = data[table].filter(item => !deleteIds.includes(item.id)); } if(actionDetail.action === 'update') { console.log('This is an UPDATE entry'); const updateMap = actionDetail.payload.reduce((acc, updatedItem) => { acc[updatedItem.id] = updatedItem; return acc; }, {}); data[table] = data[table].map(item => updateMap[item.id] || item); } } } fs.writeFileSync('output.json', JSON.stringify(data, null, 2));
How It Works with Your Example
- Your
source.jsonhas a playlist with ID1 - The
updatepayload inchanges.jsonalso has ID1with updatedsong_ids - The
map()method finds the matching ID and replaces the old playlist with the updated one - The final
output.jsonwill have the exact playlist you expect!
内容的提问来源于stack exchange,提问作者Rachel

