0

I have an array which is like this:

const AllFiles = [

    {name: "ExistingFile1", mimetype: "image/jpg", size: "500"},

    [ 
     File, // This is the New File itself (see File API)
     {name: "NewFile1", mimetype: "video/mp4", size: "9000"}
    ],

    {name: "ExistingFile2", mimetype: "video/mp4", size: "4000"},

    [ 
     File, // This is the New File itself (see File API)
     {name: "NewFile2", mimetype: "image/jpg", size: "500"}
    ],

 ]

As you can see the AllFiles array contains a mix of objects and arrays.

I need to filter the AllFiles array to only return items where the mimetype starts with "image/".

So I started off with the following:

const FilteredFiles = AllFiles.filter((FileItem, index) => FileItem.mimetype.startsWith("image/"))

The problem is that it only looks for the mimetype where it is in a top level object. Its does not look deeper where a New File has mimetype in the second level object within an array.

To get the mimetype of existing files you need to use: FileItem[0].mimetype

But to get the mimetype for new files you need to use: FileItem[0][1].mimetype

Because of this mismatch I am unable to filter the AllFiles array. How could this possibly be achieved?

1
  • What about using an if statement? You can then create a logical branch depending on wether the property exists or not Commented Feb 16 at 16:51

2 Answers 2

2

You can use a ?? operator to have a very compact solution:

const AllFiles = [{name:"ExistingFile1",mimetype:"image/jpg",size:"500"},["FILE",{name:"NewFile1",mimetype:"video/mp4",size:"9000"}],{name:"ExistingFile2",mimetype:"video/mp4",size:"4000"},["FILE",{name:"NewFile2",mimetype:"image/jpg",size:"500"}]];
 
const result = AllFiles.filter(f => (f[1] ?? f).mimetype.startsWith('image'));

result.forEach(r => console.log(JSON.stringify(r)));

1
  • 1
    this is very elegant and works thank you
    – volume one
    Commented Feb 16 at 17:36
1

A simple approach would be to check if the entity in the iteration has the mimetype property. If it does, then you can read it directly. If it does not then you can assume its an array and you need to instead read from the second entity in the array.

const File = "foo", AllFiles = [{name:"ExistingFile1",mimetype:"image/jpg",size:"500"},["foo",{name:"NewFile1",mimetype:"video/mp4",size:"9000"}],{name:"ExistingFile2",mimetype:"video/mp4",size:"4000"},["foo",{name:"NewFile2",mimetype:"image/jpg",size:"500"}]];

const filteredFiles = AllFiles.filter(entity => {
  const obj = entity.hasOwnProperty('mimetype') ? entity : entity[1];
  return obj.mimetype.startsWith("image/");
});

console.log(filteredFiles);

Note that this is only for demonstration purposes. In a production system I'd suggest a few more checks to make this more robust, such as checking the data types are as expected, but the above example is the simplistic version of the pattern to follow.

1
  • this is nice thank you
    – volume one
    Commented Feb 16 at 17:36

Not the answer you're looking for? Browse other questions tagged or ask your own question.