The Old County
The Old County

Reputation: 89

JavaScript - creating a comma delimited string from a lookup in a heavily nested array

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

Answers (5)

secan
secan

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

adiga
adiga

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

timlg07
timlg07

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

Abishek Kumar
Abishek Kumar

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

mplungjan
mplungjan

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

Related Questions