Посмотрите, как я это сделал здесь. Я прокомментировал код с деталями того, что делается.
Единственная разница в выводе состоит в том, что я сохраняю uploadImage
s в исходном объекте отправителя, а не внутри первого такого вхождения этогообъект. Я думаю, что это лучший подход с точки зрения организации данных.
const sort = (items) => {
// Let's declare some useful functions:
// isUpload tests if an item is an imageUpload while cherrypickItem returns the same object with a reduced set of key/values
const isUpload = item => item.type == "imageUpload"
const cherrypickItem = (item, keys) => keys.reduce((cherrypicked, propertyName) => ({...cherrypicked, [propertyName]: item[propertyName]}), {})
// allTypes will be an array of all items apart from imageUploads, while imageUploads will be the inverse of that
const allTypes = items.filter(item => !isUpload(item))
const imageUploads = items.filter(isUpload)
// Here we are creating a hash of the imageUploads sorted into keys by the sender id
const imageUploadsBySenderId = imageUploads.reduce((items, item) => {
return {
...items,
[item.sender]: items[item.sender] ? [...items[item.sender], item] : [item]
}
}, {})
return allTypes.map(item => {
// use our cherrypickItem function to return a reduced item object
let newItem = cherrypickItem(item, ['id', 'sender', 'type', 'userThumbnail', 'username'])
// if a lookup of our imageUploads shows that there are existing items from the sender
if (imageUploadsBySenderId[item.id]) {
// merge these into the item under the key 'images'
newItem = {
...newItem,
images: imageUploadsBySenderId[item.sender].map(imageUpload => {
return cherrypickItem(imageUpload, ['id', 'imageUploadThumbnail', 'itemId'])
})
}
}
// return the new item to the map
return newItem
})
}
const sorted = sort([
{
"id":17,
"type":"comment",
"sender":17,
"recipient":3,
"itemId":5,
"commentImageId":19,
"replyImageId":"",
"imageLikeImageId":"",
"body":"great shot",
"created":"2019-10-09T20:18:47.000Z",
"username":"golfer1",
"userThumbnail":"images/thumb.jpeg",
"imageLikeThumbnail":"images/default.jpg",
"imageUploadThumbnail":"images/default.jpg",
"imageCommentThumbnail":"images/thumb.jpeg",
"imageComment":"great shot",
"imageReplyThumbnail":"images/default.jpg",
"imageReply":""
},
{
"id":16,
"type":"imageLike",
"sender":17,
"recipient":3,
"itemId":19,
"commentImageId":"",
"replyImageId":"",
"imageLikeImageId":19,
"body":"",
"created":"2019-10-09T20:18:40.000Z",
"username":"golfer1",
"userThumbnail":"images/thumb.jpeg",
"imageLikeThumbnail":"images/thumb.jpeg",
"imageUploadThumbnail":"images/default.jpg",
"imageCommentThumbnail":"images/default.jpg",
"imageComment":"",
"imageReplyThumbnail":"images/default.jpg",
"imageReply":""
},
{
"id":15,
"type":"imageLike",
"sender":17,
"recipient":3,
"itemId":21,
"commentImageId":"",
"replyImageId":"",
"imageLikeImageId":21,
"body":"",
"created":"2019-10-09T20:18:32.000Z",
"username":"golfer1",
"userThumbnail":"images/thumb.jpeg",
"imageLikeThumbnail":"images/thumb.jpeg",
"imageUploadThumbnail":"images/default.jpg",
"imageCommentThumbnail":"images/default.jpg",
"imageComment":"",
"imageReplyThumbnail":"images/default.jpg",
"imageReply":""
},
{
"id":14,
"type":"imageUpload",
"sender":17,
"recipient":null,
"itemId":35,
"commentImageId":"",
"replyImageId":"",
"imageLikeImageId":"",
"body":"",
"created":"2019-10-09T19:23:48.000Z",
"username":"golfer1",
"userThumbnail":"images/thumb.jpeg",
"imageLikeThumbnail":"images/default.jpg",
"imageUploadThumbnail":"images/thumb.jpeg",
"imageCommentThumbnail":"images/default.jpg",
"imageComment":"",
"imageReplyThumbnail":"images/default.jpg",
"imageReply":""
},
{
"id":13,
"type":"imageUpload",
"sender":17,
"recipient":null,
"itemId":34,
"commentImageId":"",
"replyImageId":"",
"imageLikeImageId":"",
"body":"",
"created":"2019-10-09T19:23:42.000Z",
"username":"golfer1",
"userThumbnail":"images/thumb.jpeg",
"imageLikeThumbnail":"images/default.jpg",
"imageUploadThumbnail":"images/thumb.jpeg",
"imageCommentThumbnail":"images/default.jpg",
"imageComment":"",
"imageReplyThumbnail":"images/default.jpg",
"imageReply":""
},
{
"id":12,
"type":"imageUpload",
"sender":17,
"recipient":null,
"itemId":33,
"commentImageId":"",
"replyImageId":"",
"imageLikeImageId":"",
"body":"",
"created":"2019-10-09T19:23:36.000Z",
"username":"golfer1",
"userThumbnail":"images/thumb.jpeg",
"imageLikeThumbnail":"images/default.jpg",
"imageUploadThumbnail":"images/thumb.jpeg",
"imageCommentThumbnail":"images/default.jpg",
"imageComment":"",
"imageReplyThumbnail":"images/default.jpg",
"imageReply":""
},
{
"id":11,
"type":"imageUpload",
"sender":17,
"recipient":null,
"itemId":30,
"commentImageId":"",
"replyImageId":"",
"imageLikeImageId":"",
"body":"",
"created":"2019-10-09T19:04:08.000Z",
"username":"golfer1",
"userThumbnail":"images/thumb.jpeg",
"imageLikeThumbnail":"images/default.jpg",
"imageUploadThumbnail":"images/thumb.jpeg",
"imageCommentThumbnail":"images/default.jpg",
"imageComment":"",
"imageReplyThumbnail":"images/default.jpg",
"imageReply":""
}
])
console.log(sorted)
Обновление
Если вы действительно хотите получить желаемый результат в своем вопросе, то приведенного ниже должно быть достаточно. Однако я бы пересмотрел возможность повторного использования идентификатора и тем самым дублировал данные таким образом.
const sort = (items) => {
// Let's declare some useful functions:
// isUpload tests if an item is an imageUpload while cherrypickItem returns the same object with a reduced set of key/values
const isUpload = item => item.type == "imageUpload"
const cherrypickItem = (item, keys) => keys.reduce((cherrypicked, propertyName) => ({...cherrypicked, [propertyName]: item[propertyName]}), {})
// allTypes will be an array of all items apart from imageUploads, while imageUploads will be the inverse of that
const allTypes = items.filter(item => !isUpload(item))
const imageUploads = items.filter(isUpload)
// Here we are creating a hash of the imageUploads sorted into keys by the sender id
const imageUploadsBySenderId = imageUploads.reduce((items, item) => {
return {
...items,
[item.sender]: items[item.sender] ? [...items[item.sender], item] : [item]
}
}, {})
const imageUploadItems = Object.keys(imageUploadsBySenderId).map(senderId => {
return {
// hoist the first item in the array
...cherrypickItem(imageUploadsBySenderId[senderId][0], ['id', 'sender', 'type', 'userThumbnail', 'username']),
// and then nest all the items in an images property
images: imageUploadsBySenderId[senderId].map(item => cherrypickItem(item, ['id', 'imageUploadThumbnail', 'itemId']))
}
})
return allTypes.map(item => {
return cherrypickItem(item, ['id', 'sender', 'type', 'userThumbnail', 'username'])
}).concat(imageUploadItems)
}
const sorted = sort([
{
"id":17,
"type":"comment",
"sender":17,
"recipient":3,
"itemId":5,
"commentImageId":19,
"replyImageId":"",
"imageLikeImageId":"",
"body":"great shot",
"created":"2019-10-09T20:18:47.000Z",
"username":"golfer1",
"userThumbnail":"images/thumb.jpeg",
"imageLikeThumbnail":"images/default.jpg",
"imageUploadThumbnail":"images/default.jpg",
"imageCommentThumbnail":"images/thumb.jpeg",
"imageComment":"great shot",
"imageReplyThumbnail":"images/default.jpg",
"imageReply":""
},
{
"id":16,
"type":"imageLike",
"sender":17,
"recipient":3,
"itemId":19,
"commentImageId":"",
"replyImageId":"",
"imageLikeImageId":19,
"body":"",
"created":"2019-10-09T20:18:40.000Z",
"username":"golfer1",
"userThumbnail":"images/thumb.jpeg",
"imageLikeThumbnail":"images/thumb.jpeg",
"imageUploadThumbnail":"images/default.jpg",
"imageCommentThumbnail":"images/default.jpg",
"imageComment":"",
"imageReplyThumbnail":"images/default.jpg",
"imageReply":""
},
{
"id":15,
"type":"imageLike",
"sender":17,
"recipient":3,
"itemId":21,
"commentImageId":"",
"replyImageId":"",
"imageLikeImageId":21,
"body":"",
"created":"2019-10-09T20:18:32.000Z",
"username":"golfer1",
"userThumbnail":"images/thumb.jpeg",
"imageLikeThumbnail":"images/thumb.jpeg",
"imageUploadThumbnail":"images/default.jpg",
"imageCommentThumbnail":"images/default.jpg",
"imageComment":"",
"imageReplyThumbnail":"images/default.jpg",
"imageReply":""
},
{
"id":14,
"type":"imageUpload",
"sender":17,
"recipient":null,
"itemId":35,
"commentImageId":"",
"replyImageId":"",
"imageLikeImageId":"",
"body":"",
"created":"2019-10-09T19:23:48.000Z",
"username":"golfer1",
"userThumbnail":"images/thumb.jpeg",
"imageLikeThumbnail":"images/default.jpg",
"imageUploadThumbnail":"images/thumb.jpeg",
"imageCommentThumbnail":"images/default.jpg",
"imageComment":"",
"imageReplyThumbnail":"images/default.jpg",
"imageReply":""
},
{
"id":13,
"type":"imageUpload",
"sender":17,
"recipient":null,
"itemId":34,
"commentImageId":"",
"replyImageId":"",
"imageLikeImageId":"",
"body":"",
"created":"2019-10-09T19:23:42.000Z",
"username":"golfer1",
"userThumbnail":"images/thumb.jpeg",
"imageLikeThumbnail":"images/default.jpg",
"imageUploadThumbnail":"images/thumb.jpeg",
"imageCommentThumbnail":"images/default.jpg",
"imageComment":"",
"imageReplyThumbnail":"images/default.jpg",
"imageReply":""
},
{
"id":12,
"type":"imageUpload",
"sender":17,
"recipient":null,
"itemId":33,
"commentImageId":"",
"replyImageId":"",
"imageLikeImageId":"",
"body":"",
"created":"2019-10-09T19:23:36.000Z",
"username":"golfer1",
"userThumbnail":"images/thumb.jpeg",
"imageLikeThumbnail":"images/default.jpg",
"imageUploadThumbnail":"images/thumb.jpeg",
"imageCommentThumbnail":"images/default.jpg",
"imageComment":"",
"imageReplyThumbnail":"images/default.jpg",
"imageReply":""
},
{
"id":11,
"type":"imageUpload",
"sender":17,
"recipient":null,
"itemId":30,
"commentImageId":"",
"replyImageId":"",
"imageLikeImageId":"",
"body":"",
"created":"2019-10-09T19:04:08.000Z",
"username":"golfer1",
"userThumbnail":"images/thumb.jpeg",
"imageLikeThumbnail":"images/default.jpg",
"imageUploadThumbnail":"images/thumb.jpeg",
"imageCommentThumbnail":"images/default.jpg",
"imageComment":"",
"imageReplyThumbnail":"images/default.jpg",
"imageReply":""
}
])
console.log(sorted)