0

Considering this simplified formData:

FormData { "id": "id1", "timeslots[0][start]": "2023-06-10", "timeslots[0][end]": "2023-06-09", "timeslots[1][start]": "2024-06-10", "timeslots[1][end]": "2024-06-09", .... } 

or parsed object (I have access to both):

{ id: "id1", "timeslots[0][start]": "2023-06-10", "timeslots[0][end]": "2023-06-09", "timeslots[1][start]": "2024-06-10", "timeslots[1][end]": "2024-06-09", ... } 

What would be the simplest but readable way to transform timeslots into an array?
In fine, I'd like to get this object:

{ id: "id1", timeslots:[ { start: "2023-06-10", end: "2023-06-09" }, { start: "2024-06-10", end: "2024-06-09" } ] } 

I've begun with this (in JS). But I don't think it driving me somewhere...

 const timeslots = [] for (const [key, value] of Object.entries(body)) { if (key.startsWith('timeslots')) { const new_key = key.substring(13, key.length - 1) const slot = key.substring(10, 11) const tmp = { [new_key]: value, number: slot } timeslots.push(tmp) ... } } 

===== EDIT ======

Considering this augmented object:

{ id: "id1", "timeslots[0][start]": "2023-06-10", "timeslots[0][end]": "2023-06-09", "timeslots[0]disability[3]": "D3", "timeslots[0]disability[4]": "D4" "timeslots[1][start]": "2024-06-10", "timeslots[1][end]": "2024-06-09", "timeslots[1]disability[1]": "D1", "timeslots[1]disability[5]": "D5" ... } 

How to update @newalvaro9 answer to get this object?

{ id: "id1", timeslots:[ { start: "2023-06-10", end: "2023-06-09", disability: ['D3', 'D4'] }, { start: "2024-06-10", end: "2024-06-09", disability: ['D1', 'D5'] } ] } 
2

1 Answer 1

1

After some tests I arrived to this conclusion:

const inputObject = { id: "id1", "timeslots[0][start]": "2023-06-10", "timeslots[0][end]": "2023-06-09", "timeslots[1][start]": "2024-06-10", "timeslots[1][end]": "2024-06-09" }; const transformedObject = { id: inputObject.id, timeslots: Object.entries(inputObject) .filter(([key]) => key.startsWith("timeslots")) .map(([key, value]) => { const [, index, property] = key.match(/timeslots\[(\d+)\]\[(start|end)\]/); return { [property]: value, index: parseInt(index) }; }) .reduce((acc, { index, ...rest }) => { acc[index] = acc[index] || {}; Object.assign(acc[index], rest); return acc; }, []) }; console.log(transformedObject);

The above code creates a new Object based in the inputObject. For timeslots we retrieve the properties of the inputObject into an array of key-value pairs with Object.entries, then we only need only the keys that are timeslots so we .filter() the array. The remaining key-value pairs are mapped using .map() to extract the index and property name from the key using a regular expression. We then use .reduce() to merge the resulting objects into a single array of timeslot objects. The index property is used as the index in the array. If a timeslot object with the same index already exists, its properties are merged with the new object using Object.assign().

================= Edited question answer: ===================

const inputObject = { id: "id1", "timeslots[0][start]": "2023-06-10", "timeslots[0][end]": "2023-06-09", "timeslots[0]disability[3]": "D3", "timeslots[0]disability[4]": "D4", "timeslots[1][start]": "2024-06-10", "timeslots[1][end]": "2024-06-09", "timeslots[1]disability[1]": "D1", "timeslots[1]disability[5]": "D5" }; // Convert the input object into the desired format const timeslots = []; const keys = Object.keys(inputObject); keys.forEach(key => { const match = key.match(/timeslots\[(\d+)\]\[(start|end)\]/); if (match) { const index = parseInt(match[1]); const prop = match[2]; if (!timeslots[index]) { timeslots[index] = {}; } timeslots[index][prop] = inputObject[key]; } else { const matchDisability = key.match(/timeslots\[\d+\]disability\[(\d+)\]/); if (matchDisability) { const index = parseInt(matchDisability[0].split('[')[1]); const disability = inputObject[key]; if (!timeslots[index].disability) { timeslots[index].disability = []; } timeslots[index].disability.push(disability); } } }); const outputObject = { id: inputObject.id, timeslots }; console.log(outputObject.timeslots);

Im not going to explain this time, you should learn and try to understand the javascript functions and methods

Sign up to request clarification or add additional context in comments.

2 Comments

Not so simple to grasp, but fully working! Thanks.
I've edited my question with an edge case. Any idea? Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.