英文:
fs.readFileSync gives duplicated results when reading JSON files in node.js
问题
The issue you're encountering seems to be related to the reuse of the dataToSort
object across different months. When you reuse the same object for both April and May, it accumulates data from both months. To fix this issue, you should initialize the dataToSort
object inside the for
loop for each month. Here's the corrected code for your understanding:
let months = ["apr", "may"];
function getDataFromJSONFile(month) {
let jsonData = fs.readFileSync(`sorted/${month}-total2.json`);
let convertedData = JSON.parse(jsonData);
return convertedData;
}
function arrayToObject(data) {
let dataToSort = {}; // Initialize a new object for each month
data.forEach((user) => {
dataToSort[user[0].toString()] = user[1];
});
return dataToSort;
}
for (let i in months) {
let currentMonth = months[i];
console.log("Current month is " + currentMonth);
let getDataForMonth = getDataFromJSONFile(currentMonth);
let convertedMonth = arrayToObject(getDataForMonth);
if (convertedMonth.hasOwnProperty("John") == true) {
console.log(true);
}
}
By initializing dataToSort
inside the arrayToObject
function for each month, you ensure that the data from previous months doesn't accumulate, and the code should work as intended.
英文:
I got two JSON files that I'm processing:
- sorted/apr-total2.json
- sorted/may-total2.json
There are files for other months of the year, but for debugging purposes I'm focusing on these two because they are causing the problem.
They contain simple data in the following format:
[
["John", 1403],
["Peter", 1159],
...
]
However, John is available only in sorted/apr-total2.json file and not in sorted/may-total2.json.
My code is the following:
let months = ["apr", "may"];
let dataToSort = {};
function getDataFromJSONFile(month) {
let jsonData = fs.readFileSync(`sorted/${month}-total2.json`);
let convertedData = JSON.parse(jsonData);
return convertedData;
}
function arrayToObject(data) {
data.forEach((user) => {
dataToSort[user[0].toString()] = user[1];
});
return dataToSort;
}
for (let i in months) {
let currentMonth = months[i];
console.log("Current month is " + currentMonth);
let getDataForMonth = getDataFromJSONFile(currentMonth);
let convertedMonth = arrayToObject(getDataForMonth);
if (convertedMonth.hasOwnProperty("John") == true) {
console.log(true);
}
}
My output is the following:
Current month is apr
true
Current month is may
true
This isn't correct, since user John isn't available in sorted/may-total2.json. So why is this happening? It seems that the object convertedMonth is causing the issue.
If I add the following code at the end of the for loop and delete the ConvertedMonth object properties:
for (let item in convertedMonth) {
delete convertedMonth[item];
}
It works as intended:
Current month is apr
true
Current month is may
I want to know why this object is causing the issue, because I reused the same code in another place of my project.
答案1
得分: 3
Your arrayToObject
function uses a single global dataToSort
, so any entries will be accumulated and overwritten there. See:
let dataToSort = {};
function arrayToObject(data) {
data.forEach((user) => {
dataToSort[user[0].toString()] = user[1];
});
return dataToSort;
}
arrayToObject([["foo", 123]])
{ foo: 123 }
arrayToObject([["foo", 456], ["bar", 567]])
{ foo: 456, bar: 567 }
Your program simplifies to something like
let months = ["apr", "may"];
for (let currentMonth of months) {
console.log("Current month is " + currentMonth);
let jsonData = JSON.parse(fs.readFileSync(`sorted/${month}-total2.json`));
let convertedMonth = Object.fromEntries(jsonData);
if (convertedMonth["John"]) {
console.log(true);
}
}
which
- uses
for..of
for correct and simpler iteration over the months - uses
Object.fromEntries
to convert an array of 2-arrays into a plain object (which is what yourarrayToObject
did)
英文:
Your arrayToObject
function uses a single global dataToSort
, so any entries will be accumulated and overwritten there. See:
> let dataToSort = {};
> function arrayToObject(data) {
... data.forEach((user) => {
... dataToSort[user[0].toString()] = user[1];
... });
... return dataToSort;
... }
> arrayToObject([["foo", 123]])
{ foo: 123 }
> arrayToObject([["foo", 456], ["bar", 567]])
{ foo: 456, bar: 567 }
Your program simplifies to something like
let months = ["apr", "may"];
for (let currentMonth of months) {
console.log("Current month is " + currentMonth);
let jsonData = JSON.parse(fs.readFileSync(`sorted/${month}-total2.json`));
let convertedMonth = Object.fromEntries(jsonData);
if (convertedMonth["John"]) {
console.log(true);
}
}
which
- uses
for..of
for correct and simpler iteration over the months - uses
Object.fromEntries
to convert an array of 2-arrays into a plain object (which is what yourarrayToObject
did)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论