在 forEach 循环中应用带有索引的颜色

Applying color with index in forEach loop

假设我有一组颜色;

availableColors = ['#aee3d8', ' #d1caae', '#e7e1f9'];

我有对象数组,对象是这样的。

[{
        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,
    }]

如何在映射用户时按索引应用不同的颜色?

    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
    }

你可以使用 Generator and Iterator 来做这种事情。

这将始终为您拥有的许多用户重复提供给 *getColor() 的数组中提供的颜色。它使用 ininfite 循环和 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);

这也不会像您希望的那样从“开始”开始,除非您创建一个新的迭代器。

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);
}

编辑

正如 Nick Parsons 所指出的,您可以使用以下方法使生成器更加优雅。

/**
 * 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;
}

此外,如果您想将数组视为不可变的(您通常希望这样做),则需要调整 map() 函数,如下所示。

const usersWithColors = users.map(user => ({ ...user, backgroundColor: iter.next().value }))

应用以上所有内容,您将得到以下实现:

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)