Reputation: 89
I am building a drag and drop application -- that is given a multidimensional array of supported file type and titles for those file types and icons to use against them in a legend. The drag and drop picks up an accept array that has specific mime types -- I need to display to the user in easy terms what file types are allowed -- so return a comma delimited string - jpg, pdf
what is the best way of looping through the multidimensional array to get at the key in the forms to complete this task?
getAcceptedFileTypes(){
let supportedFiles = [{
"images": {
"icon": <ImageIcon />,
"formats": [{"png": "image/png"}, {"jpeg": "image/jpeg"}],
}
},{
"compressed_files": {
"icon": <DescriptionIcon />,
"formats": [{"zip": "application/x-zip-compressed"}, {"rar": "application/x-rar-compressed"}],
}
},{
"documents": {
"icon": <FileCopyIcon />,
"formats": [{"pdf": "application/pdf"}, {"docx": "application/msword"}, {"doc": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}],
}
}];
let accept = ["application/pdf","image/jpeg"]
console.log("supportedFiles", supportedFiles);
console.log("accept", accept);
let acceptedFiles = "jpeg, pdf";
return (
acceptedFiles
)
}
Upvotes: 0
Views: 144
Reputation: 2679
You could do something like:
let supportedFiles = [{
"images": {
"icon": "<ImageIcon />",
"formats": [{
"png": "image/png"
}, {
"jpeg": "image/jpeg"
}],
}
}, {
"compressed_files": {
"icon": "<DescriptionIcon />",
"formats": [{
"zip": "application/x-zip-compressed"
}, {
"rar": "application/x-rar-compressed"
}],
}
}, {
"documents": {
"icon": "<FileCopyIcon />",
"formats": [{
"pdf": "application/pdf"
}, {
"docx": "application/msword"
}, {
"doc": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
}],
}
}];
let accept = ["application/pdf", "image/jpeg"];
const acceptedFiles = supportedFiles.reduce((acc, item) => {
const subItem = Object.values(item)[0];
subItem.formats.forEach((format, index) => {
if (accept.indexOf(Object.values(format)[0]) > -1) {
acc.push(Object.keys(subItem.formats[index])[0]);
}
});
return acc;
}, []).join(', ');
//test
console.log(acceptedFiles);
Upvotes: 2
Reputation: 35222
If this is an recurring operation, you can create a mapper object which maps each MIME type to its file extension name
const mapper = {}
for (const file of supportedFiles) {
const { formats } = Object.values(file)[0]
for (const format of formats) {
const [key, value] = Object.entries(format)[0]
mapper[value] = key;
}
}
function getAcceptedFiles(accept, mapper) {
return accept.map(t => mapper[t])
}
Mapper object:
{
"image/png": "png",
"image/jpeg": "jpeg",
"application/x-zip-compressed": "zip",
"application/x-rar-compressed": "rar",
"application/pdf": "pdf",
"application/msword": "docx",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "doc"
}
Here's a snippet:
const supportedFiles=[{images:{icon:"",formats:[{png:"image/png"},{jpeg:"image/jpeg"}],}},{compressed_files:{icon:"",formats:[{zip:"application/x-zip-compressed"},{rar:"application/x-rar-compressed"}],}},{documents:{icon:"",formats:[{pdf:"application/pdf"},{docx:"application/msword"},{doc:"application/vnd.openxmlformats-officedocument.wordprocessingml.document"}],}}];
const mapper = {}
for (const file of supportedFiles) {
const { formats } = Object.values(file)[0]
for (const format of formats) {
const [key, value] = Object.entries(format)[0]
mapper[value] = key;
}
}
function getAcceptedTypes(accept, mapper) {
return accept.map(t => mapper[t])
}
console.log( getAcceptedTypes( ["application/pdf","image/jpeg"], mapper) )
console.log( getAcceptedTypes( ["application/x-rar-compressed"], mapper) )
Upvotes: 0
Reputation: 626
Here is a simple solution using 3 nested for loops.
function getAcceptedFileExtensions() {
let acceptedExtensions = [];
for (let fileTypeObject of supportedFiles) {
for (let fileTypeKey of Object.keys(fileTypeObject)) {
for (let extensionPair of fileTypeObject[fileTypeKey].formats) {
acceptedExtensions.push(Object.keys(extensionPair)[0]);
}
}
}
return acceptedExtensions;
}
console.log(getAcceptedFileExtensions().toString());
The data structure is a bit weird as it contains an array of objects containing one key, which seems to be the name of each object, instead of e.g. an object with the different file-type-categories directly. Because of that the second loop could be shortened to Object.keys(fileTypeObject)[0]
:
const supportedFiles = [
{
"images": {
"icon": "<ImageIcon />",
"formats": [
{ "png": "image/png" },
{ "jpeg": "image/jpeg" }
],
}
},
{
"compressed_files": {
"icon": "<DescriptionIcon />",
"formats": [
{ "zip": "application/x-zip-compressed" },
{ "rar": "application/x-rar-compressed" }
],
}
},
{
"documents": {
"icon": "<FileCopyIcon />",
"formats": [
{ "pdf": "application/pdf" },
{ "docx": "application/msword" },
{ "doc": "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }
],
}
}
];
function getAcceptedFileExtensions() {
let acceptedExtensions = [];
for (let fileTypeObject of supportedFiles) {
let fileTypeKey = Object.keys(fileTypeObject)[0];
for (let extensionPair of fileTypeObject[fileTypeKey].formats) {
acceptedExtensions.push(Object.keys(extensionPair)[0]);
}
}
return acceptedExtensions;
}
console.log(getAcceptedFileExtensions().toString());
Upvotes: 0
Reputation: 539
Might wanna try this
let supportedFiles = [{
"images": {
"icon": '<ImageIcon />',
"formats": [{"png": "image/png"}, {"jpeg": "image/jpeg"}],
}
},{
"compressed_files": {
"icon": '<DescriptionIcon />',
"formats": [{"zip": "application/x-zip-compressed"}, {"rar": "application/x-rar-compressed"}],
}
},{
"documents": {
"icon": '<FileCopyIcon />',
"formats": [{"pdf": "application/pdf"}, {"docx": "application/msword"}, {"doc": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}],
}
}];
let acceptedFiles=[];
supportedFiles.forEach((fileType)=>{
Object.keys(fileType).forEach(key=>{
fileType[key].formats.forEach(format=>{
acceptedFiles.push(Object.keys(format));
})
})
})
console.log(acceptedFiles.join(","))
If you change the structure then:
let supportedFilesObj ={
"images": {
"icon": '<ImageIcon />',
"formats": [{"png": "image/png"}, {"jpeg": "image/jpeg"}],
},
"compressed_files": {
"icon": '<DescriptionIcon />',
"formats": [{"zip": "application/x-zip-compressed"}, {"rar": "application/x-rar-compressed"}],
},
"documents": {
"icon": '<FileCopyIcon />',
"formats": [{"pdf": "application/pdf"}, {"docx": "application/msword"}, {"doc": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}],
}
};
let acceptedFiles=[];
Object.keys(supportedFilesObj).forEach((key)=>{
supportedFilesObj[key].formats.forEach(format=>{
acceptedFiles.push(Object.keys(format));
})
})
console.log(acceptedFiles.join(","))
Upvotes: 0
Reputation: 178094
You mean this?
const getAcceptedFileTypes = () => {
let supportedFiles = [{
"images": {
"icon": `<ImageIcon />`,
"formats": [{
"png": "image/png"
}, {
"jpeg": "image/jpeg"
}],
}
}, {
"compressed_files": {
"icon": `<DescriptionIcon />`,
"formats": [{
"zip": "application/x-zip-compressed"
}, {
"rar": "application/x-rar-compressed"
}],
}
}, {
"documents": {
"icon": `<FileCopyIcon />`,
"formats": [{
"pdf": "application/pdf"
}, {
"docx": "application/msword"
}, {
"doc": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
}],
}
}];
let acceptedFiles = supportedFiles.flatMap(file => file[Object.keys(file)[0]].formats)
return (
acceptedFiles
)
}
console.log(getAcceptedFileTypes())
console.log(getAcceptedFileTypes().map(entry => Object.keys(entry)[0]).join(","))
Upvotes: 0