Cómo filtrar una matriz que tiene tipos de datos mixtos
Tengo una matriz que es así:
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"}
],
]
Como puede ver, la AllFiles
matriz contiene una combinación de objetos y matrices.
Necesito filtrar la AllFiles
matriz para devolver solo elementos donde mimetype
comienza "image/"
.
Entonces comencé con lo siguiente:
const FilteredFiles = AllFiles.filter((FileItem, index) => FileItem.mimetype.startsWith("image/"))
El problema es que sólo busca dónde mimetype
está en un objeto de nivel superior. No profundiza en dónde un archivo nuevo tiene mimetype
un objeto de segundo nivel dentro de una matriz.
Para obtener los mimetype
archivos existentes, debe utilizar:FileItem[0].mimetype
Pero para obtener mimetype
archivos nuevos necesitas usar:FileItem[0][1].mimetype
Debido a esta discrepancia, no puedo filtrar la AllFiles
matriz. ¿Cómo podría lograrse esto?
Puede utilizar un ??
operador para tener una solución muy compacta:
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)));
Un enfoque sencillo sería comprobar si la entidad en la iteración tiene la mimetype
propiedad. Si es así, puedes leerlo directamente. Si no es así, puede asumir que es una matriz y, en su lugar, debe leer desde la segunda entidad de la matriz.
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);
Tenga en cuenta que esto es sólo para fines de demostración. En un sistema de producción, sugeriría algunas comprobaciones más para que esto sea más sólido, como verificar que los tipos de datos sean los esperados, pero el ejemplo anterior es la versión simplista del patrón a seguir.