Я создаю приложение для перетаскивания, которому предоставляется многомерный массив поддерживаемых типов файлов и заголовков для этих типов файлов и значков, которые можно использовать против них в легенде. Перетаскивание выбирает массив принятия, который имеет определенные типы mime - мне нужно простым языком показать пользователю, какие типы файлов разрешены - поэтому верните строку с разделителями-запятыми - jpg, pdf
как лучше всего пройти через многомерный массив, чтобы получить ключ в формах для выполнения этой задачи?
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.info("supportedFiles", supportedFiles);
console.info("accept", accept);
let acceptedFiles = "jpeg, pdf";
return (
acceptedFiles
)
}
Что это за рамки? Пожалуйста, отметьте
либо следуйте тому, что предлагает @adiga, либо преобразуйте supportedFiles
в объект, чтобы вы могли использовать Object.keys()
для прокрутки
Структура данных не соответствует ванильному JavaScript. Так что парсить/фильтровать его с помощью ванильного JavaScript будет довольно сложно.
но - supportFiles - это массив объектов - он также дополняет легенду информацией о значке
как мне реорганизовать поддерживаемые файлы как объект - поместите «имя: изображение» в качестве свойства, которое вы имеете в виду
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"}], } };
Вы имеете в виду это?
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.info(getAcceptedFileTypes())
console.info(getAcceptedFileTypes().map(entry => Object.keys(entry)[0]).join(","))
нет - я имею в виду взять принятый массив - что перетаскивание тоже чувствительно - посмотреть на поддерживаемый массив - и выбрать ключи типа файла - отображая его в виде списка с разделителями-запятыми - например png, jpg, zip
let acceptFiles = "jpeg, pdf"; -- это демонстрация того, что я хочу, чтобы acceptFiles стал
См. последний console.info
верно -- но речь шла о сравнении массива mimetypes -- с полным списком поддержки в многомерном массиве там
Может попробовать это
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.info(acceptedFiles.join(","))
Если изменить структуру, то:
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.info(acceptedFiles.join(","))
Если это повторяющаяся операция, вы можете создать объект сопоставления, который сопоставляет каждый тип MIME с его именем расширения файла.
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])
}
Объект карты:
{
"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"
}
Вот фрагмент:
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.info( getAcceptedTypes( ["application/pdf","image/jpeg"], mapper) )
console.info( getAcceptedTypes( ["application/x-rar-compressed"], mapper) )
Вот простое решение с использованием 3 вложенных циклов for.
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.info(getAcceptedFileExtensions().toString());
Структура данных немного странная, так как она содержит массив объектов, содержащих один ключ, который, кажется, является именем каждого объекта, а не, например. объект с различными категориями типов файлов напрямую. Из-за этого второй цикл можно сократить до 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.info(getAcceptedFileExtensions().toString());
Вы можете сделать что-то вроде:
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.info(acceptedFiles);
спасибо ты единственный кто понял
Если возможно, вы должны изменить структуру на что-то вроде
{ name: "pdf", MIMEtype: "application/pdf" }
. Фильтровать с динамическими именами ключей сложнее. Кроме того, это позволит вам добавить больше свойств, если это необходимо, например,"MaxAllowedSize"
для загрузки и т. д.