用重复的元素组织多维数组

时间:2019-06-17 18:40:35

标签: javascript sorting multidimensional-array replace

我写了一个代码来帮助我快速组织我的d&d游戏。它基本上会产生一个input:number个居民,随机描述他们的种族和年龄组:

var numero = document.getElementById('numero') //INPUT:NUMBER

function encontroaleatorio1() {
    var arrRaça = ['human (male)', 'human (male)', 'human (male)', 'human (female)', 'human (female)', 'human (female)', 'elf (male)', 'elf (male)', 'elf (female)', 'elf (female)', 'half-elf (male)', 'half-elf (female)', 'half-orc (male)', 'half-orc (female)', 'gnome (male)', 'gnome (female)']
    var arrIdade = ['very young', 'young', 'adult', 'old']
    var raça = []
    var idade = []

    //RANDOM (RACE AND AGE)
    if (numero.value > 0) {
        for (i=0; i < numero.value; i++) {
            var arrRaça2 = arrRaça[Math.floor(Math.random() * arrRaça.length)]
            raça.push(arrRaça2)
            var arrIdade2 = arrIdade[Math.floor(Math.random() * arrIdade.length)]
            idade.push(arrIdade2)
        }
    } else if (numero.length == 0) {
        alert('Número inválido')
    } else {
        alert('Número inválido')
    }

    //SORT AND REGROUP REPEATED ELEMENTS
    raça.sort()
    var raça2 = []
    var nrepetidos = [] //ARRAY WITH REPEATED RACES
    var current = null;
    var cnt = 0;
    for (var i = 0; i < raça.length; i++) {
        if (raça[i] != current) {
            if (cnt > 0) {
                raça2.push(`${cnt} ${current}`)
                nrepetidos.push(cnt)
            }
            current = raça[i];
            cnt = 1;
        } else {
            cnt++;
        }
    }
    if (cnt > 0) {
        raça2.push(`${cnt} ${current}`)
        nrepetidos.push(cnt)
    }

    //GROUP RACES AND AGES
    var idade2 = []
    var total = []
    var nr = 0
    for (var i = 0; i<raça2.length; i++) {
        var ni = nr
        nr += nrepetidos[i]
        idade2.push(idade.slice(ni, nr))
        total.push(`${raça2[i]} : ${idade2[i]}`)
    }

    //CHANGE "," BY " || "
    for (i=0; i<total.length; i++) {
        total[i] = total[i].replace(/,/g, ' || ')
    }

    //WRITE
    for (var i=0; i<total.length; i++) {
        document.write(total[i]+ "<br /><br />");
      }
}

最后,如果input:number = 10我有类似的内容:

1 elf (female) : very young

3 elf (male) : adult || young || adult

1 gnome (male) : young

1 human (female) : adult

4 human (male) : young || very young || very young || old

input:number的值很低(如10)时,可以读取结果,但值较高时会变得复杂。有什么办法可以将其组织为:

1 elf (female) : very young

3 elf (male) : 2 adult || young

1 gnome (male) : young

1 human (female) : adult

4 human (male) : young || 2 very young || old

但是仍然保留随机属性吗?

2 个答案:

答案 0 :(得分:0)

// defining inputs
let number = 1000
const races = ['human (male)', 'human (male)', 'human (male)', 'human (female)', 'human (female)', 'human (female)', 'elf (male)', 'elf (male)', 'elf (female)', 'elf (female)', 'half-elf (male)', 'half-elf (female)', 'half-orc (male)', 'half-orc (female)', 'gnome (male)', 'gnome (female)']

const ages = ['very young', 'young', 'adult', 'old']

// generate random character list
let charList = generateChar(number, races, ages)

// group by race THEN age
const grouped = groupByAge(groupByRace(charList))

// display resulting HTML
document.write(createHtmlTemplate(grouped))

// random character generation function
function generateChar(charNum, raceArr, ageArr) {
  const ret = []
  for (let i = 0; i < charNum; i++) {
    ret.push({
      race: raceArr[Math.floor(Math.random() * raceArr.length)],
      age: ageArr[Math.floor(Math.random() * ageArr.length)]
    })
  }
  return ret
}

// grouping by race
function groupByRace(charArr) {
  let ret = {}
  for (let key of charArr) {
    if (!(key.race in ret)) {
      ret[key.race] = []
    }
    ret[key.race].push(key.age)
  }
  return ret
}

// grouping by age groups
function groupByAge(charArr) {
  let ret = []

  for (let entry of Object.entries(charArr)) {
    let item = {}
    item.race = entry[0]
    item.count = entry[1].length
    item.ageGroups = {}
    for (let key of entry[1]) {
      if (!(key in item.ageGroups)) {
        item.ageGroups[key] = 0
      }
      item.ageGroups[key]++
    }
    ret.push(item)
  }
  return ret
}

// creating HTML string
function createHtmlTemplate(groupedList) {
  let html = ''
  groupedList.forEach(item => {
    html += `${item.count} ${item.race} : `
    for (let key of Object.keys(item.ageGroups)) {
      html += `${item.ageGroups[key]} ${key} || `
    }
    html += '<br /><br />'
  })
  return html
}

唯一的事情是每行比赛结束时的 ||

答案 1 :(得分:0)

您可以使用一个对象来保存数据,这样更容易处理

const races = ['human (male)', 'human (male)', 'human (male)', 'human (female)', 'human (female)', 'human (female)', 'elf (male)', 'elf (male)', 'elf (female)', 'elf (female)', 'half-elf (male)', 'half-elf (female)', 'half-orc (male)', 'half-orc (female)', 'gnome (male)', 'gnome (female)'];

const ageGroups = ['very young', 'young', 'adult', 'old'];

// helper function to get a random element from an array
const randomElement = arr => arr[Math.floor(Math.random() * arr.length)];

// a function to get random n element from races and ageGroups arrays
const magic1 = (races, ageGroups, n) => {
  const obj = {};
  for (let i = 0; i < n; i++) {
    const ageGroup = randomElement(ageGroups);
    const race = randomElement(races);
    if (!obj[race]) obj[race] = {};
    if (!obj[race][ageGroup]) obj[race][ageGroup] = 0;
    obj[race][ageGroup]++;
  }
  return obj;
};

// a function to convert the object returned by magic1 to an array of strings with the same format you wanted
const magic2 = (obj) => {
  const res = [];
  for (var prop in obj) {
    const ageGroups = [];
    let acc = 0;
    for (var ageGroup in obj[prop]) {
      const count = obj[prop][ageGroup];
      acc += count;
      ageGroups.push((count === 1 ? '' : `${count} `) + ageGroup);
    }
    res.push(`${acc} ${prop} : ${ageGroups.join(' || ')}`);
  }
  return res;
};

console.log(magic2(magic1(races, ageGroups, 10)));