如何像专业人员一样将数组合并为对象数组



我必须将三个数组合并为一个对象数组,其中每个I对象都包含每个数组中的值I。

我有三个数组,其中包含来自firebase的数据(缩略图的url数组、全尺寸图像的url数组和带有元数据的对象数组(

let finalArrayOfImagesAndMetadata = [];
// Getting array of download url's for every file
const getDownloadUrlFullFile =  await Promise.all(getAllFilesList.items.map(itemRef => getDownloadURL(itemRef)));
const getDownloadUrlThumbnails = await Promise.all(getAllThumbnails.items.map(itemRef => getDownloadURL(itemRef)));
// Getting metadata for all files
const getMetadataForAllFiles = await Promise.all(getAllFilesList.items.map(itemRef => getMetadata(itemRef)));

我已经设法开发了两种解决这个问题的方法:

第一个:

// Merging full size image url, thumbnail url and metadata in one object
const processArray = async () => {
getDownloadUrlFullFile.forEach((o)=>{
finalArrayOfImagesAndMetadata.push({'fullImageUrl': o});
});
getDownloadUrlThumbnails.forEach((x, i)=>{
finalArrayOfImagesAndMetadata[i].imageUrl =x;
})
getMetadataForAllFiles.forEach((x, i)=>{
const element = x.customMetadata;
finalArrayOfImagesAndMetadata[i] = {...finalArrayOfImagesAndMetadata[i], ...element};
})
console.log(finalArrayOfImagesAndMetadata)
return finalArrayOfImagesAndMetadata;
}

第二:

// Merging full size image url, thumbnail url and metadata in one object
const processArray = async () => {
return new Promise(async function (resolve, reject) {
for (let i =0 ; i<getDownloadUrlFullFile.length; i++){
const getSpecificFileThumbnail = getDownloadUrlThumbnails[i];
const getFileMetadata = loadedMetaData[i].customMetadata;
const imageUrl = {'imageUrl': getSpecificFileThumbnail};
const fullImageUrl = {'fullImageUrl': getDownloadUrlFullFile[i]}
finalArrayOfImagesAndMetadata.push({...getFileMetadata, ...imageUrl, fullImageUrl});
if ( finalArrayOfImagesAndMetadata.length === getDownloadUrlThumbnails.length) {
return (finalArrayOfImagesAndMetadata);
}
resolve (finalArrayOfImagesAndMetadata);
}})}

这两种解决方案都有效,但是,有没有更复杂、更好的方法来解决这个问题?也许需要等待,直到写入数组的每一步都完成?

换句话说:如何像专业人士一样做到这一点?

您可以像第一个选项一样迭代元素,但使用map方法来构造新数组。然后你可以使用index参数来获取其他数据(就像你的第二个选项(,所以:

const mergedArray = getDownloadUrlFullFile.map((fullImageUrl, i)=>({
// Shorthand to set fullImageUrl: fullImageUrl
fullImageUrl,
// assign the property directly
'imageUrl': getSpecificFileThumbnail[i],
// You can also spread values if you want them directly on the object
{...loadedMetaData[i].customMetadata}
}));

如果要将请求和数据合并在一起,可以使用Promise.all和Promise.map模式https://www.techiediaries.com/promise-all-map-async-await-example/

是的,有几种方法取决于结果数据的所需形状。。。

const urls =  await Promise.all(getAllFilesList.items.map(itemRef => getDownloadURL(itemRef)));
const thumbnails = await Promise.all(getAllThumbnails.items.map(itemRef => getDownloadURL(itemRef)));
const metadata = await Promise.all(getAllFilesList.items.map(itemRef => getMetadata(itemRef)));
// simplest merge is just a concatenation
const oneBigArray = [...urls, ...thumbnails, ...metadata]
// another sort of merge is to have the arrays as props in an object
const oneBigObject = { urls, thumbnails, metadata }; // notice no spread ... operator

一个真正的";合并";将关闭数组中每个对象中的一些共同点,以构建一个对象数组,如:

[
{ key: 'some common key',
url: 'some url',
thumbnail: 'some url',
metadata: { /* some meta data object */ }
},
// ...
];

这里的详细说明需要了解更多关于返回对象的信息,例如,如果每个返回对象中都有一个键,将它们与其他数组中的朋友联系起来。

@danh

// simplest merge is just a concatenation
const oneBigArray = [...urls, ...thumbnails, ...metadata]

这看起来很酷!任何将密钥添加到每个"…"的方法。。。url";,拥有这样的所有url?

{imageUrl: www....,
thumbnailUrl: www...,
metadata : {}
}

@Assaf

我也很喜欢你的做法。我不认为我可以在一次遍历中对每个数组使用迭代器,这很好。

谢谢大家。我会毫不留情地缩短代码。

最新更新