Reputation:
currently I have an array levels
containing other arrays called level
and these ones contain stages
.
I want to map all objects within a level with a new property called position
. This position returns the distance from the center of the array. By center I mean the length / 2.
If the arrays length is even I want the following range
... -3.5 , -2.5 , -1.5 , -0.5 , 0.5 , 1.5 , 2.5 , 3.5 ...
If the arrays length is not even I want the following range
... -4 , -3 , -2 , -1 , 0 , 1 , 2 , 3 , 4 ...
I started creating this
const distanceLevels = [
[{
"id": 1
}, {
"id": 8
}],
[{
"id": 2
}],
[{
"id": 3
}, {
"id": 4
}, {
"id": 5
}, {
"id": 7
}],
[{
"id": 6
}]
];
function getViewLevels() {
const viewLevels = []; // the new array as the result
distanceLevels.forEach(level => { // one level containing the stages
const levelLength = level.length;
const halfLevelLength = levelLength * 0.5;
const levelLengthIsEven = levelLength % 2 == 0;
let viewLevel = []; // the mapped level
if (levelLengthIsEven) {
addViewStage(viewLevel, level[Math.floor(halfLevelLength)], 0);
}
for (let i = 0; i < halfLevelLength; i++) {
let rightPosition = i - halfLevelLength;
let leftPosition = i;
let leftStageIndex = i;
if (levelLengthIsEven) {
leftPosition++;
leftStageIndex += Math.floor(halfLevelLength) + 1;
} else {
rightPosition += 0.5;
leftPosition += 0.5;
leftStageIndex += halfLevelLength;
}
addViewStage(viewLevel, level[i], rightPosition);
addViewStage(viewLevel, level[leftStageIndex], leftPosition);
}
viewLevel = viewLevel.sort((a, b) => a.position > b.position); // sort the result by their position, means from negative to positive
viewLevels.push(viewLevel); // add this new view level
});
console.log(viewLevels); // <---- result here!
}
function addViewStage(viewLevel, stage, position) { // push a new element to the array
viewLevel.push({
stage: stage,
position: position
});
}
getViewLevels();
This is the result I get
I really struggle with the math. All I want to do is to map each object in level from
stage (object)
to
{
stage: stage,
position: position // with the correct range
}
Upvotes: 8
Views: 734
Reputation: 2920
You can do that with two nested maps
:
const distanceLevels = [
[{
"id": 1
}, {
"id": 8
}],
[{
"id": 2
}],
[{
"id": 3
}, {
"id": 4
}, {
"id": 5
}, {
"id": 7
}],
[{
"id": 6
}]
]
const mappedLevels = distanceLevels.map(level =>
level.map((stage, index, lvl) => (
{...stage, position: index - (lvl.length - 1) / 2}
))
);
console.log(mappedLevels);
Upvotes: 5
Reputation: 5870
Try this:
let levels = [
[
{
stage: 1
},
{
stage: 2
},
],
[
{
stage: 1
},
{
stage: 2
},
{
stage: 3
},
],
[
{
stage: 1
},
{
stage: 2
},
{
stage: 3
},
{
stage: 4
},
{
stage: 5
},
],
[
{
stage: 1
},
{
stage: 2
},
]
]
levels.forEach(function(level) {
let len = level.length,
shift = (level.length + 1) / 2;
level.map(function(stage, index) {
stage.position = (index + 1) - shift;
})
});
console.log(levels);
Upvotes: 1