Reputation: 2494
I'm struggling to find a good solution to process my array of objects.
I have two arrays:
let structure = ["horizontal","vertical","small","small","small"]
let items = [{"id":1,"title":"xxxxx","format":"horizontal","position":0},
{"id":3,"title":"xxxxx","format":"vertical","position":1},
{"id":6,"title":"xxxxx","format":"small","position":2},
{"id":9,"title":"xxxxx","format":"small","position":3},
{"id":11,"title":"xxxxx","format":"small","position":4}]
Edit: Items are more complex than this: it has about 15 attributes...
structure
has a dynamic length and is my reference array. When I change structure
I must remap the items array changing the format according to structure
. So if I change structure
to
let structure = ["horizontal","vertical","vertical","vertical","small"]
The array must change to
let items = [{"id":1,"title":"xxxxx","format":"horizontal","position":0},
{"id":3,"title":"xxxxx","format":"vertical","position":1},
{"id":6,"title":"xxxxx","format":"vertical","position":2},
{"id":9,"title":"xxxxx","format":"vertical","position":3},
{"id":11,"title":"xxxxx","format":"small","position":4}]
This can be done with a map.
This is my Vue method, I map the structure and use the function changeStructure
I change the format.
methods: {
changeStructure(object,structure) {
object.format = structure
return object
},
updateCoverElements() {
let structure = this.coverTypes[this.currentCoverVersion]
let elements = this.coverElements
let changeStructure = this.changeStructure
let revisedElement = structure.map(function(structure, index) {
return changeStructure(elements[index],structure)
});
console.log(revisedElement);
}
},
But the problem is that, as I told before, structure has a dynamic length.
So when I change to
let structure = ["horizontal","vertical","vertical"]
Item results must be
let items = [{"id":1,"title":"xxxxx","format":"horizontal","position":0},
{"id":3,"title":"xxxxx","format":"vertical","position":1},
{"id":6,"title":"xxxxx","format":"vertical","position":2}]
This is not a problem, if the new structure
length has less elements.
But when I change to
let structure = ["horizontal","vertical","vertical","vertical","vertical","vertical","vertical"]
Item results must be
let items = [{"id":1,"title":"xxxxx","format":"horizontal","position":0},
{"id":3,"title":"xxxxx","format":"vertical","position":1},
{"id":6,"title":"xxxxx","format":"vertical","position":2},
{"id":"","title":"","format":"vertical","position":3},
{"id":"","title":"","format":"vertical","position":4},
{"id":"","title":"","format":"vertical","position":5},
{"id":"","title":"","format":"vertical","position":6}]
And here is the problem: I cannot find a good way to dynamically create an object with the same identical structure as other items objects (a copy), with every field empty except for position, the index of the array, and format.
Upvotes: 0
Views: 1516
Reputation: 35222
You could use the spread syntax like this. If items
has a value at the index
, it will overwrite the default id
and title
values.
let structure = ["horizontal","vertical","vertical","vertical","vertical","vertical","vertical"]
let items = [{"id":1,"title":"xxxxx","format":"horizontal","position":0},
{"id":3,"title":"xxxxx","format":"vertical","position":1},
{"id":6,"title":"xxxxx","format":"vertical","position":2}]
const defaultObj = { id: '', title: '' }
const newItems = structure.map((format, position) => {
return { ...defaultObj, ...items[position], format, position }
})
console.log(newItems)
Upvotes: 2
Reputation: 27594
Just slice off a new copy of items with max structure.length
items, then iterate through your new clone of items and set each format
attribute. Finally, create new objects for any elements in structure
that don't have a corresponding partner in items
:
var structure = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
var items = [
{'id':1,'title':'xxxxx','format':'horizontal','position':0},
{'id':3,'title':'xxxxx','format':'vertical', 'position':1},
{'id':6,'title':'xxxxx','format':'vertical', 'position':2},
];
// update all extant items
var _items = Object.assign([], items.slice(0, structure.length));
_items.forEach(function(i, idx) { i.format = structure[idx] });
// create any new items
for (var i=_items.length; i<structure.length; i++) {
_items.push(Object.assign({}, items[0], {
id: '',
title: '',
position: i,
format: structure[i],
}))
}
console.log(_items)
Upvotes: 1
Reputation: 8740
The best way to solve this problem using map()
method would be to organize your implementation functional so that you could call it many times with a different set of data wherever you need (the concept of reusability).
Here is what I have tried. I have defined the function named getAlteredArray(items, structure)
which returns the desired array. Note that if you are looking to use map() method means you want a new array (I mean you don't want to alter the passed array).
I have pasted the o/p on the code itself (it is commented out).
// function that creates new array with desired items and returns to the caller
function getAlteredArray(items, structure) {
let newArr = items.map((obj, index) => {
// obj => {"id":1,"title":"xxxxx","format":"horizontal","position":0}
obj["format"] = structure[index]
return obj
})
return newArr
}
// function that creates set of data needs to be passed to getAlteredArray() function
function test() {
let items = [{"id":1,"title":"xxxxx","format":"horizontal","position":0},
{"id":3,"title":"xxxxx","format":"vertical","position":1},
{"id":6,"title":"xxxxx","format":"small","position":2},
{"id":9,"title":"xxxxx","format":"small","position":3},
{"id":11,"title":"xxxxx","format":"small","position":4}]
// TEST 1 - Call getAlteredArray() with `items` & `structure`
let structure = ["horizontal","vertical","vertical","vertical","small"]
let newArr = getAlteredArray(items, structure)
console.log(newArr)
/*
[ { id: 1, title: 'xxxxx', format: 'horizontal', position: 0 },
{ id: 3, title: 'xxxxx', format: 'vertical', position: 1 },
{ id: 6, title: 'xxxxx', format: 'vertical', position: 2 },
{ id: 9, title: 'xxxxx', format: 'vertical', position: 3 },
{ id: 11, title: 'xxxxx', format: 'small', position: 4 } ]
*/
// TEST 2
let structure2 = ["horizontal","vertical","small","small","small"]
let newArr2 = getAlteredArray(items, structure2)
console.log(newArr2)
/*
[ { id: 1, title: 'xxxxx', format: 'horizontal', position: 0 },
{ id: 3, title: 'xxxxx', format: 'vertical', position: 1 },
{ id: 6, title: 'xxxxx', format: 'small', position: 2 },
{ id: 9, title: 'xxxxx', format: 'small', position: 3 },
{ id: 11, title: 'xxxxx', format: 'small', position: 4 } ]
*/
}
// Start
test()
Upvotes: 0