从加权类别中选择唯一字符串的最有效方法

时间:2018-07-04 12:07:00

标签: javascript arrays performance

设置:

  • n个类别
  • 每个类别都有一个权重(表示该类别重要性的人为数字)
  • 每个字符串都是全局唯一的

示例:

  • 类别:a,b,c
  • 字符串:
    • a_001,a_002,a_003
    • b_001,b_002,b_003
    • c_001,c_002,c_003
  • 重量:
    • a:1
    • b:2
    • c:1

任务:

获取一个唯一字符串数组,其中1个来自类别a,2个来自类别b,1个来自类别c。从类别中选择的字符串数量不必与weightedNumber完全一致。挑选琴弦时,应仅考虑(但应牢记)重量。但是,如果不可能的话,那就不是世界末日了。但是,选择的字符串总数必须正确。

问题:

  • 权重可能为10,但该类别中只有3个唯一的字符串(在这种情况下,应根据权重用其他类别的字符串填充)
  • 我正在使用Firestore,因此一次只能选择一个随机字符串,并且无法访问给定类别中的字符串数

我的尝试

function pickStrings(numberOfStrings, arrCategories) {
  // Calculates the weight of each category
  // Sets initial weight and stringsleft to weightTotal and numberOfStrings
  // Iterates over the categories:
  //    selectedStrings.push(...pickStringsFromCategory(calculatedNumberBasedOnWeight, categoryId))
  // returns selectedStrings
}

function pickStringsFromCategory(numberOfStrings, categoryid) {
  // Create a map of picked strings
  // Randomly pick a string from that category
  // Checks if the string was picked already
  // Tries again (up to 10 times) if the string was already picked
}

但是,那感觉并不对。尝试10次是一个人工数字,如果只有1个字符串且weightedNumber为10的类别是最后一个,则选择的字符串数小于numberOfStrings。

关于如何改进此算法的任何想法?

1 个答案:

答案 0 :(得分:1)

这里是一种可能的方法:

var arr = [
  ["a_001", "a_002", "a_003"],
  ["b_001", "b_002", "b_003"],
  ["c_001", "c_002", "c_003"]
];

var weights = [7, 2, 1];

var str = "";
weights.map((o, i) => {

  let curr = i;
  let p = 0;
  for (let j = 0; j < o; j++) {
    if (arr[curr][p]) {//this could be and ajax, function, whatever
      str += arr[curr][p] + " ";//this is an assumption
      p++;
    } else { //this happens when we didn't find a string into such category 
      curr = curr + 1; //we move one category
      p = 0;//firs element in the next category
      j--;//move back because we didn't finish
    }
  }

})

console.log(str);