我必須將三個陣列合并為一個物件陣列,其中每個 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);
}})}
兩種解決方案都有效,但是,有沒有更復雜和更好的方法來解決這個問題?也許要等到寫入陣列的每一步都完成?
換句話說:如何像專業人士一樣做?
uj5u.com熱心網友回復:
您可以像第一個選項一樣迭代元素,但使用 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/
uj5u.com熱心網友回復:
是的,有幾種方法取決于結果資料的所需形狀......
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 */ }
},
// ...
];
在這里詳細說明需要了解有關回傳物件的更多資訊,例如,每個回傳物件中是否有一個鍵將它們與其他陣列中的朋友聯系起來。
uj5u.com熱心網友回復:
@danh
// simplest merge is just a concatenation
const oneBigArray = [...urls, ...thumbnails, ...metadata]
這看起來很酷!有什么方法可以為每個“... urls”添加密鑰,讓所有 url 都像這樣?
{imageUrl: www....,
thumbnailUrl: www...,
metadata : {}
}
@Assaf
我也很喜歡你的做法。我不認為我可以一次對每個陣列使用迭代器,很好。
謝謝你們。我肯定會縮短代碼。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/418764.html
標籤:
