I've got an array of objects:
Input
[
{ file: '1.pdf', text: 'Page: 1 / 2' },
{ file: '2.pdf', text: 'Page: 2 / 2' },
// -- '1.pdf':['1.pdf','2.pdf']
{ file: '3.pdf', text: 'Page: 1 / 3' },
{ file: '4.pdf', text: 'Page: 2 / 3' },
{ file: '5.pdf', text: 'Page: 3 / 3' },
// -- '2.pdf':['3.pdf','4.pdf', '5.pdf']
{ file: '6.pdf', text: 'Page: 1 / 4' },
{ file: '7.pdf', text: 'Page: 2 / 4' },
{ file: '8.pdf', text: 'Page: 3 / 4' },
{ file: '9.pdf', text: 'Page: 4 / 4' }
// -- '3.pdf':['6.pdf','7.pdf', '8.pdf', '9.pdf']
]
And I wanna group them deponds on the number of pages of each one like this Output:
{
"1.pdf": ["1.pdf", "2.pdf"],
"2.pdf": ["3.pdf", "4.pdf", "5.pdf"],
"3.pdf": ["6.pdf", "7.pdf", "8.pdf", "9.pdf"],
};
My Attempt:
let arr = [
{ file: "1.pdf", text: "Page: 1 / 2" },
{ file: "2.pdf", text: "Page: 2 / 2" },
{ file: "3.pdf", text: "Page: 1 / 3" },
{ file: "4.pdf", text: "Page: 2 / 3" },
{ file: "5.pdf", text: "Page: 3 / 3" },
{ file: "6.pdf", text: "Page: 1 / 4" },
{ file: "7.pdf", text: "Page: 2 / 4" },
{ file: "8.pdf", text: "Page: 3 / 4" },
{ file: "9.pdf", text: "Page: 4 / 4" },
];
let result = {};
let i = 0;
let x = null;
let visited = [];
for (const { file, text } of arr) {
let val = text.split("/").at(-1).trim();
let key = null;
if (!visited.includes(val)) {
key = i ".pdf";
x = key;
visited.push(val);
} else {
key = x;
}
result[key] ??= [];
result[key].push(file);
}
console.log(result);
This works well in case where there's unique number of pages, BUT When there's the same number of pages on other it fails and combines them all to one instead of create new one:
[
{ file: '1.pdf', text: 'Page: 1 / 2' },
{ file: '2.pdf', text: 'Page: 2 / 2' },
{ file: '3.pdf', text: 'Page: 1 / 3' },
{ file: '4.pdf', text: 'Page: 2 / 3' },
{ file: '5.pdf', text: 'Page: 3 / 3' },
{ file: '6.pdf', text: 'Page: 1 / 4' },
{ file: '7.pdf', text: 'Page: 2 / 4' },
{ file: '8.pdf', text: 'Page: 3 / 4' },
{ file: '9.pdf', text: 'Page: 4 / 4' },
{ file: '10.pdf', text: 'Page: 1 / 2' },
{ file: '11.pdf', text: 'Page: 2 / 2' },
]
Output:
{
"1.pdf": ["1.pdf", "2.pdf"],
"2.pdf": ["3.pdf", "4.pdf", "5.pdf"], // vvvvvvvvvvvvvvvvvv
"3.pdf": ["6.pdf", "7.pdf", "8.pdf", "9.pdf", "10.pdf", "11.pdf"],
};
Expected Output:
{
"1.pdf": ["1.pdf", "2.pdf"],
"2.pdf": ["3.pdf", "4.pdf", "5.pdf"],
"3.pdf": ["6.pdf", "7.pdf", "8.pdf", "9.pdf"],
"4.pdf": ["10.pdf", "11.pdf"],
};
CodePudding user response:
CODE
var array = [
{ file: '1.pdf', text: 'Page: 1 / 2' },
{ file: '2.pdf', text: 'Page: 2 / 2' },
{ file: '3.pdf', text: 'Page: 1 / 3' },
{ file: '4.pdf', text: 'Page: 2 / 3' },
{ file: '5.pdf', text: 'Page: 3 / 3' },
{ file: '6.pdf', text: 'Page: 1 / 4' },
{ file: '7.pdf', text: 'Page: 2 / 4' },
{ file: '8.pdf', text: 'Page: 3 / 4' },
{ file: '9.pdf', text: 'Page: 4 / 4' },
{ file: '10.pdf', text: 'Page: 1 / 2' },
{ file: '11.pdf', text: 'Page: 2 / 2' },
];
var ret = {};
var lastGroup = 0;
array.forEach(function (value, i) {
if(value.text.includes("Page: 1 /")){
lastGroup ;
ret[lastGroup ".pdf"]=[];
}
ret[lastGroup ".pdf"].push(value.file);
});
console.log(ret);
OUTPUT
{
"1.pdf": [
"1.pdf",
"2.pdf"
],
"2.pdf": [
"3.pdf",
"4.pdf",
"5.pdf"
],
"3.pdf": [
"6.pdf",
"7.pdf",
"8.pdf",
"9.pdf"
],
"4.pdf": [
"10.pdf",
"11.pdf"
]
}
CodePudding user response:
Here's a solution using reduce
to iterate over the array of objects, writing a new value to the output whenever we encounter a Page: 1
or at the end of the array:
const arr = [
{ file: '1.pdf', text: 'Page: 1 / 2' },
{ file: '2.pdf', text: 'Page: 2 / 2' },
{ file: '3.pdf', text: 'Page: 1 / 3' },
{ file: '4.pdf', text: 'Page: 2 / 3' },
{ file: '5.pdf', text: 'Page: 3 / 3' },
{ file: '6.pdf', text: 'Page: 1 / 4' },
{ file: '7.pdf', text: 'Page: 2 / 4' },
{ file: '8.pdf', text: 'Page: 3 / 4' },
{ file: '9.pdf', text: 'Page: 4 / 4' },
{ file: '10.pdf', text: 'Page: 1 / 2' },
{ file: '11.pdf', text: 'Page: 2 / 2' },
]
const result = arr.reduce(({ fnum, pages, files }, { file, text }, i, a) => {
const pgnum = text.match(/Page: (\d )/)[1]
if (i == a.length - 1) {
pages.push(file)
files[`${ fnum}.pdf`] = pages
return files
}
else if (pgnum == 1 && pages.length) {
files[`${ fnum}.pdf`] = pages
pages = [file]
}
else {
pages.push(file)
}
return { fnum, pages, files }
}, { fnum : 0, pages : [], files : {} });
console.log(result)