How could I separate each JSON object and group them to an array in JavaScript?

跟風遠走 提交于 2021-02-17 03:31:17

问题


example of req.files from multer.js

[
    {
        fieldname: files0,
        originalname: 'Screenshot from 2020-05-23 01-52-30.png',
        encoding: '7bit',
        mimetype: 'image/png',
        destination: 'public/uploads/projects/0a480789-eb14-4fe4-bb89-44aa741efe33/proposals/chma00000133',
        filename: '1606822252923_Screenshot from 2020-05-23 01-52-30.png',
        path: 'public/uploads/projects/0a480789-eb14-4fe4-bb89-44aa741efe33/proposals/chma00000133/1606822252923_Screenshot from 2020-05-23 01-52-30.png',
        size: 172092
      },
      {
        fieldname: files0,
        originalname: 'Screenshot from 2020-05-22 08-44-05.png',
        encoding: '7bit',
        mimetype: 'image/png',
        destination: 'public/uploads/projects/0a480789-eb14-4fe4-bb89-44aa741efe33/proposals/chma00000133',
        filename: '1606822252925_Screenshot from 2020-05-22 08-44-05.png',
        path: 'public/uploads/projects/0a480789-eb14-4fe4-bb89-44aa741efe33/proposals/chma00000133/1606822252925_Screenshot from 2020-05-22 08-44-05.png',
        size: 440592
      },
      {
        fieldname: files1,
        originalname: 'Screenshot from 2020-05-30 11-36-42.png',
        encoding: '7bit',
        mimetype: 'image/png',
        destination: 'public/uploads/projects/0a480789-eb14-4fe4-bb89-44aa741efe33/proposals/chma00000133',
        filename: '1606822252930_Screenshot from 2020-05-30 11-36-42.png',
        path: 'public/uploads/projects/0a480789-eb14-4fe4-bb89-44aa741efe33/proposals/chma00000133/1606822252930_Screenshot from 2020-05-30 11-36-42.png',
        size: 477511
      },
      {
        fieldname: files1,
        originalname: 'Screenshot from 2020-05-30 11-36-36.png',
        encoding: '7bit',
        mimetype: 'image/png',
        destination: 'public/uploads/projects/0a480789-eb14-4fe4-bb89-44aa741efe33/proposals/chma00000133',
        filename: '1606822252931_Screenshot from 2020-05-30 11-36-36.png',
        path: 'public/uploads/projects/0a480789-eb14-4fe4-bb89-44aa741efe33/proposals/chma00000133/1606822252931_Screenshot from 2020-05-30 11-36-36.png',
        size: 223362
      },
      {
        fieldname: files1,
        originalname: 'Screenshot from 2020-05-30 11-36-31.png',
        encoding: '7bit',
        mimetype: 'image/png',
        destination: 'public/uploads/projects/0a480789-eb14-4fe4-bb89-44aa741efe33/proposals/chma00000133',
        filename: '1606822252932_Screenshot from 2020-05-30 11-36-31.png',
        path: 'public/uploads/projects/0a480789-eb14-4fe4-bb89-44aa741efe33/proposals/chma00000133/1606822252932_Screenshot from 2020-05-30 11-36-31.png',
        size: 260419
      }
]

I want to dynamically group each JSON objects with their fieldname and store them in an array of objects while using their fieldname number as their array index.

The groups can be between 0 to 9, depending on the user input.

The result I'm hoping for is something like

someArr = [

    [
        {
            fieldname: files0
            originalname: somevalue,
            ...
            size: some value
        },
        {
            fieldname: files0,
            originalname: somevalue,
            ...
            size: some value
        },
    ]
        ,
    [
        
        {
            fieldname: files1,
            originalname: somevalue,
            ...
            size: some value
        },
        {
            fieldname: files1,
            originalname: somevalue,
            ...
            size: some value
        },
        {
            fieldname: files1,
            originalname: somevalue,
            ...
            size: some value
        },
    ]
    ...
    
]

and if it exists, someArr[9] would return

[

    {
        fieldname: files9,
        originalname: somevalue,
        ...
        size: some value
    },
    {
        fieldname: files9,
        originalname: somevalue,
        ...
        size: some value
    },
]

What I've tried was first parse integers from fieldnames and reassign them as their values for better sorting with for-loops

Object.keys(req.files).forEach((key) => {
  const thisFile = req.files[key];
  const thisFileGroup = parseInt(thisFile.fieldname.match(/\d/g).join(''), 10); 
  // rename fieldname from files0, files1 ... to 0 , 1 ....
  req.files[key].fieldname = thisFileGroup;
});

But from here, I can't find where to push this element(thisFile) to, since I cannot predeclare each arrays at the upper scope since they also need to be created dynamically.


回答1:


I would use reduce

const data = [ 
{ fieldname: 'files0', originalname: 'Screenshot from 2020-05-23 01-52-30.png', },
{ fieldname: 'files0', originalname: 'Screenshot from 2020-05-22 08-44-05.png', },
{ fieldname: 'files1', originalname: 'Screenshot from 2020-05-30 11-36-42.png', },
{ fieldname: 'files1', originalname: 'Screenshot from 2020-05-30 11-36-36.png', },
{ fieldname: 'files1', originalname: 'Screenshot from 2020-05-30 11-36-31.png', }],
arr = data.reduce((acc, cur) => {
  const idx = cur.fieldname.replace("files",""); // get 0, 1
  if (acc[idx]) acc[idx].push(cur); // if already there, just push
  else acc[idx] = [cur];            // otherwise initialise
  return acc;
},[]) 

console.log(arr)

NOTE: The groups can be between 0 to 9, depending on the user input.

I assume there are no holes since that could result in a sparse array so

data = [ 
     { fieldname : 'files0' },
     { fieldname : 'files0' },
     { fieldname : 'files3' },
     { fieldname : 'files3' },
 }

would create an array of

[
  [ { fieldname : 'files0' }, { fieldname : 'files0' } ],
  null,
  null,
  [ { fieldname : 'files3' }, { fieldname : 'files3' } ],
]



回答2:


If you don't need necessarily an order by index files[index]

you could in that case Array.prototype.reduce() to Object.
Your object will be grouped by fieldname properties (not by alphabetical order though) containing one array with the items having that same property key.
Iterate your object using Object.values() (and Array.prototype.forEach() if needed).

const data = [
  { fieldname: "files0", originalname: '0-a'},
  { fieldname: "files0", originalname: '0-b'},
  { fieldname: "files1", originalname: '1-a'},
  { fieldname: "files1", originalname: '1-b'},
  { fieldname: "files1", originalname: '1-c'},
];

const byFieldName = data.reduce((ob, d) => {
  if (!ob.hasOwnProperty(d.fieldname)) ob[d.fieldname] = [];
  ob[d.fieldname].push(d);
  return ob;
}, {});

// console.log(byFieldName); // Uncomment to see how it looks like
console.log( Object.values(byFieldName) );



回答3:


I try to not modify your logic to do that.
If there is no files2, filesArray[2] will be undefined.

// Omit other fields
const req = {
    files: [
        { fieldname: "files0", originalname: 'Screenshot from 2020-05-23 01-52-30.png'},
        { fieldname: "files0", originalname: 'Screenshot from 2020-05-22 08-44-05.png'},
        { fieldname: "files1", originalname: 'Screenshot from 2020-05-30 11-36-42.png'},
        { fieldname: "files1", originalname: 'Screenshot from 2020-05-30 11-36-36.png'},
        { fieldname: "files1", originalname: 'Screenshot from 2020-05-30 11-36-31.png'},
        { fieldname: "files3", originalname: 'Screenshot from 2020-05-30 11-36-42.png'},
        { fieldname: "files3", originalname: 'Screenshot from 2020-05-30 11-36-36.png'},
        { fieldname: "files3", originalname: 'Screenshot from 2020-05-30 11-36-31.png'}
    ]
}

let filesArray = []

for (let file of req.files) {
    const thisFileGroup = parseInt(file.fieldname.match(/\d/g).join(''), 10);
    if (!filesArray[thisFileGroup]) {
        filesArray[thisFileGroup] = []
    }
    filesArray[thisFileGroup].push(file)
}

console.log(filesArray[2]) // will be undefined
console.log(filesArray[1]) // will be files1 array
console.log(filesArray)


来源:https://stackoverflow.com/questions/65090523/how-could-i-separate-each-json-object-and-group-them-to-an-array-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!