How to assign and iterate only once over array?

Solution 1:

It's a good practice, when you hear "random without duplicates", to think "shuffle".

So to assign random, non-repeating, correctly gendered avatars, segregate the avatars by gender, shuffle the male and female avatars, then assign them sequentially to users....

const avatars = getAvatars();  // just to move the data to the bottom of the snippet
const users = getUsers();

const shuffledMales = shuffle(avatars.filter(a => a.gender==="male"));
const shuffledFemales = shuffle(avatars.filter(a => a.gender==="female"));

let maleIndex = 0, femaleIndex = 0;
users.forEach(user => {
  user.avatar = user.gender === "male" ? shuffledMales[maleIndex++] : shuffledFemales[femaleIndex++];
});

console.log(users);

// fisher-yates shuffle, adapted from https://bost.ocks.org/mike/shuffle/
function shuffle(array) {
  let copy = [],
    n = array.length,
    i;
  while (n) {
    let i = Math.floor(Math.random() * array.length);
    if (i in array) {
      copy.push(array[i]);
      delete array[i];
      n--;
    }
  }
  return copy;
}

function getAvatars() {
  return [{
      "id": 1,
      "image": "maleavatar1",
      "gender": "male"
    },
    {
      "id": 2,
      "image": "maleavatar2",
      "gender": "male"
    },
    {
      "id": 3,
      "image": "maleavatar3",
      "gender": "male"
    },
    {
      "id": 4,
      "image": "femaleavatar1",
      "gender": "female"
    },
    {
      "id": 5,
      "image": "femaleavatar2",
      "gender": "female"
    },
    {
      "id": 6,
      "image": "femaleavatar3",
      "gender": "female"
    },
    {
      "id": 7,
      "image": "femaleavatar4",
      "gender": "female"
    },
  ];
}

function getUsers() {
  return [{
      "id": 1,
      "name": "Manila",
      "gender": "female"
    },
    {
      "id": 2,
      "name": "Josy",
      "gender": "female"
    },
    {
      "id": 3,
      "name": "Eliza",
      "gender": "female"
    },
    {
      "id": 4,
      "name": "Martin",
      "gender": "male"
    },
    {
      "id": 5,
      "name": "Mark",
      "gender": "male"
    },
    {
      "id": 6,
      "name": "John",
      "gender": "male"
    }
  ];
}