Let's say i have array of the colors;
availableColors = ['#aee3d8', ' #d1caae', '#e7e1f9'];
and I have the array of the Objects with object like this.
[{
name: 'Name',
surname: 'Surname',
timeOff: '8:05 AM',
imageSource: null,
};
{
name: 'Name',
surname: 'Surname',
timeOff: '8:05 AM',
imageSource: someUrl,
};
{
name: 'Name',
surname: 'Surname',
timeOff: '8:05 AM',
imageSource: null,
}]
How can I apply the different color by index when mapping user?
public applyUserPictureColor(): void {
this.users.push(this.user, this.user, this.user, this.user);
const users = this.users.map((user) => {
if (!user.imageSource) {
return {
...user,
bg: this.colorIndex(),
};
}
});
this.users = users;
}
private colorIndex(): void {
this.availableColors
}
CodePudding user response:
You could use a Generator and Iterator to do this kind of thing.
This will always repeat the colors provided in the array given to *getColor()
for however many users you have. It does this using and ininfite loop and modular arithmetic.
const availableColors = ["#aee3d8", "#d1caae", "#e7e1f9"];
/**
* Cyclic generator to always get the next color from a given range of colors.
* @param {Array<string>} allColors
*/
function* getColor(allColors) {
let i = 0;
while (true) {
yield allColors[i];
i = (i 1) % allColors.length;
}
}
// get the iterator to be able to always get the next color
const iter = getColor(availableColors);
const users = [
{
name: "Name",
surname: "Surname",
timeOff: "8:05 AM",
imageSource: "",
},
{
name: "Name2",
surname: "Surname",
timeOff: "8:05 AM",
imageSource: "",
},
{
name: "Name3",
surname: "Surname",
timeOff: "8:05 AM",
imageSource: "",
},
{
name: "Name4",
surname: "Surname",
timeOff: "8:05 AM",
imageSource: null,
},
{
name: "Name5",
surname: "Surname",
timeOff: "8:05 AM",
imageSource: "",
},
{
name: "Name6",
surname: "Surname",
timeOff: "8:05 AM",
imageSource: null,
},
];
const usersWithColors = users.map(user => {
// use iterator to get next color
user.backgroundColor = iter.next().value;
return user;
})
console.log(usersWithColors);
This will also not start at the "beginning" again like you want it to behave, except when you create a new iterator.
const availableColors = ["#aee3d8", "#d1caae", "#e7e1f9"];
/**
* Cyclic generator to always get the next color from a given range of colors.
* @param {Array<string>} allColors
*/
function* getColor(allColors) {
let i = 0;
while (true) {
yield allColors[i];
i = (i 1) % allColors.length;
}
}
let iterator = getColor(availableColors);
for (let index = 0; index < 5; index ) {
console.log(iterator.next().value);
}
// the next value of iterator.next().value would be #e7e1f9
// but now we assign a new iterator and start from the beginning again
iterator = getColor(availableColors);
console.log("Start over...")
for (let index = 0; index < 2; index ) {
console.log(iterator.next().value);
}
Edit
As Nick Parsons pointed out you can make the generator more elegant by using the following.
/**
* Cyclic generator to always get the next color from a given range of colors.
* @param {Array<string>} allColors
*/
function* getColor(allColors) {
while (true) yield* allColors;
}
Also if you want to treat your array as immutable, which you usually would like to do, you need to adjust the map()
function as shown below.
const usersWithColors = users.map(user => ({ ...user, backgroundColor: iter.next().value }))
Applying all of the above you will get to the following implementation:
const availableColors = ["#aee3d8", "#d1caae", "#e7e1f9"];
/**
* Cyclic generator to always get the next color from a given range of colors.
* @param {Array<string>} allColors
*/
function* getColor(allColors) {
while (true) yield* allColors;
}
// get the iterator to be able to always get the next color
const iter = getColor(availableColors);
const users = [
{
name: "Name",
surname: "Surname",
timeOff: "8:05 AM",
imageSource: "",
},
{
name: "Name2",
surname: "Surname",
timeOff: "8:05 AM",
imageSource: "",
},
{
name: "Name3",
surname: "Surname",
timeOff: "8:05 AM",
imageSource: "",
},
{
name: "Name4",
surname: "Surname",
timeOff: "8:05 AM",
imageSource: null,
},
{
name: "Name5",
surname: "Surname",
timeOff: "8:05 AM",
imageSource: "",
},
{
name: "Name6",
surname: "Surname",
timeOff: "8:05 AM",
imageSource: null,
},
];
const usersWithColors = users.map(user => ({ ...user, backgroundColor: iter.next().value }))
// this is now a new array
console.log("New array with background color information")
console.log(usersWithColors);
// users is not changed
console.log("Unchanged users")
console.log(users)