I have this string it represent a chart of accounts
"1: Comptes de capitaux
10\. Capital et Réserves.
101\. Capital.
1011\. Capital souscrit - non appelé.
1012\. Capital souscrit - appelé, non versé.
1013\. Capital souscrit - appelé, versé.
10131\. Capital non amorti.
10132\. Capital amorti.
1018\. Capital souscrit soumis à une réglementation particulière.
105\. Ecarts de réévaluation.
108\. Compte de l'exploitant. "
I want this output :
"1":
{ id:"1",
accountName: "Comptes de capitaux",
children:{
id:"10",
accountName: "Capital et Réserves" ,
children:{
id:"101",
accountName:"Capital",
children: {
id:"1011",
accountName:"Capital souscrit - non appelé",
children: {...}
},{
id:"1012",
accountName:"Capital souscrit - appelé, non versé",
children: {...}
},...
},{
id:"105",
accountName:"Ecarts de réévaluation",
children: {}
},{...}
}
}
The solution should correctly create the tree structure with the parent-child relationships based on the account ID this my solution and is always wrong it does not correctly create the tree structure above can you provide me the right answer or the error i have commited in my code
function createChartOfAccountsTree(input) {
// Split the input by line
const lines = input.split("\n");
// Create an object to store the accounts
let accounts = {};
// Loop through each line
for (let i = 0; i < lines.length; i ) {
// Split the line by space
let parts = lines[i].split(" ");
// Extract the ID and account name
let id = parts[0];
let accountName = parts.slice(1).join(" ");
// remove the dot from account name
accountName = accountName.replace(".","");
// Create an account object
let account = {
id,
accountName,
children: {}
};
// Check if the account is a child of an existing account
let parentId = id.slice(0, -1);
let parent = accounts[parentId];
if (parent) {
// If the account has a parent, add it as a child
parent.children[id] = account;
} else {
// If the account does not have a parent, it's a top level account
accounts[id] = account;
}
}
return accounts;
}
console.log(createChartOfAccountsTree("1 : Comptes de capitaux\n10. Capital et Réserves.\n101.Capital.\n1011. Capital souscrit - non appelé.\n1012. Capital souscrit - appelé, non versé.\n1013. Capital souscrit - appelé, versé.\n10131. Capital non amorti.\n10132. Capital amorti.\n1018. Capital souscrit soumis à une réglementation particulière.\n105. Ecarts de réévaluation.\n108. Compte de l'exploitant. ")); ```
CodePudding user response:
There are a few issues:
The input seems to not have the same format on each line. In the example, the first line has a colon after the number (or a space and a colon -- as in your code), while other lines have a point after the number.
In either case, your current code does not remove those delimiters when they come right after the initial number. So there is no child-parent match when you just remove the final character from the id to identify the parent -- as you only remove that point or colon (when there is no space before it). If the input format is really that varying, then you could use a regular expression to identify the two parts in each line.
The code seems to want
children
to be a plain object whose keys areid
values, but your desired output section does not specify such keys -- it representschildren
as if it is an array but with an invalid syntax.As you want to identify each parent with
accounts[parentId]
, you must make sure that every entry is logged inaccounts
, not just the top level. So theelse
should be revised. Maybe use a separate variable that serves for logging the top level accounts only.
Here is your code with the above issues handled:
function createChartOfAccountsTree(input) {
// Split the input by line, and immediately identify
// the numeric prefix, and exclude final point
const lines = input.matchAll(/^(\d )[ .:] (.*?)\.?[ ]*$/gm);
// Create an object to store all the accounts
const accounts = {};
// ...and one for the top-level accounts
const top = {};
// Loop through each line, grabbing the parts
for (const [, id, accountName] of lines) {
// Create an account object
let account = {
id,
accountName,
children: {}
};
// Check if the account is a child of an existing account
let parentId = id.slice(0, -1);
let parent = accounts[parentId];
if (parent) {
// If the account has a parent, add it as a child
parent.children[id] = account;
} else {
// If the account does not have a parent, it's a top level account
top[id] = account;
}
// Log all accounts:
accounts[id] = account;
}
return top;
}
const input = `1: Comptes de capitaux
10. Capital et Réserves.
101. Capital.
1011. Capital souscrit - non appelé.
1012. Capital souscrit - appelé, non versé.
1013. Capital souscrit - appelé, versé.
10131. Capital non amorti.
10132. Capital amorti.
1018. Capital souscrit soumis à une réglementation particulière.
105. Ecarts de réévaluation.
108. Compte de l'exploitant. `;
console.log(createChartOfAccountsTree(input));