如何像专业人士一样将数组合并到对象数组中?
How to merge arrays into array of objects like a pro?
我必须将三个数组合并为一个对象数组,其中每个对象包含每个数组中的值 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);
}})}
这两种解决方案都有效,但是有没有更复杂更好的方法来解决这个问题?
也许等到写入数组的每一步都完成?
换句话说:如何做到专业?
是的,有几种方法取决于结果数据的所需形状...
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 */ }
},
// ...
];
此处的详细说明需要更多地了解返回的对象,例如,如果每个返回的对象中都有一个键将它们与其他数组中的朋友联系起来。
您可以像第一个选项一样遍历元素,但使用 map 方法构造新数组。然后你可以使用索引参数来获取其他数据(比如你的第二个选项)所以:
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/
@danh
// simplest merge is just a concatenation
const oneBigArray = [...urls, ...thumbnails, ...metadata]
这看起来很酷!有什么方法可以将密钥添加到每个“...urls”,让所有 url 都像这样?
{imageUrl: www....,
thumbnailUrl: www...,
metadata : {}
}
@阿萨夫
我也很喜欢你的做法。
我不认为我可以一次性对每个数组使用迭代器,很好。
谢谢大家。我一定会缩短代码。
我必须将三个数组合并为一个对象数组,其中每个对象包含每个数组中的值 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);
}})}
这两种解决方案都有效,但是有没有更复杂更好的方法来解决这个问题? 也许等到写入数组的每一步都完成?
换句话说:如何做到专业?
是的,有几种方法取决于结果数据的所需形状...
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 */ }
},
// ...
];
此处的详细说明需要更多地了解返回的对象,例如,如果每个返回的对象中都有一个键将它们与其他数组中的朋友联系起来。
您可以像第一个选项一样遍历元素,但使用 map 方法构造新数组。然后你可以使用索引参数来获取其他数据(比如你的第二个选项)所以:
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/
@danh
// simplest merge is just a concatenation
const oneBigArray = [...urls, ...thumbnails, ...metadata]
这看起来很酷!有什么方法可以将密钥添加到每个“...urls”,让所有 url 都像这样?
{imageUrl: www....,
thumbnailUrl: www...,
metadata : {}
}
@阿萨夫
我也很喜欢你的做法。 我不认为我可以一次性对每个数组使用迭代器,很好。
谢谢大家。我一定会缩短代码。