【问题标题】:How to find all no repeat combinations form specific single arrays use Javascript如何使用Javascript从特定的单个数组中查找所有不重复的组合
【发布时间】:2026-02-03 04:30:01
【问题描述】:

我是一名 Javascript 初学者,我有一个个人项目来使用程序来查找特定数组中所有可能且不重复的组合

我假设有 3 套产品,每套有 10 种款式,比如这个数组

[1,2,3,4..10,1,2,4...8,9,10]

①②③④⑤⑥⑦⑧⑨⑩
①②③④⑤⑥⑦⑧⑨⑩
①②③④⑤⑥⑦⑧⑨⑩

总数组长度 = 30

我打算将它随机分成5个孩子,但他们不能重复相同的产品风格

确定结果: ①②③④⑤⑥ ✔ ②③④⑤⑥⑦ ✔ ①②③⑧⑨⑩ ✔ ④⑥⑦⑧⑨⑩ ✔ ①⑤⑦⑧⑨⑩ ✔

每个人都可以平均分配不重复的产品

错误: ①②③④⑤⑥ ✔ ①②③④⑤⑦ ✔ ①②⑥⑧⑨⑩ ✔ ③④⑤⑦⑧⑨ ✔ ⑥⑦⑧⑨⑩⑩✘(因为10号重复)


我的解决方案是随机分配5组数组,然后使用“new Set(myArray[i]).size;”检查值 sum 是否为 30,使用 [do..white],而 sum 不是 30 然后重复执行随机分配功能,直到结果不重复。

像这样:

function splitArray() {
  
    do {
      var productArray = [1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10];  //Just for sample, actualy this array will be more then 30
      var productPerChildArray = [];
      for (var i = 0; i < 5; i++) {
        GroupNum = [];
  
        for (var v = 0; v < 6; v++) {
          var selectNum = productArray[Math.floor(Math.random() * productArray.length)];
          GroupNum.push(selectNum);
          productArray = removeItemOnce(productArray, selectNum);
        }
  
        productPerChildArray.push(GroupNum);
      }
    } while (checkIfArrayIsUnique(productPerChildArray));
  
    return productPerChildArray;
  }
  
  //---------check repeat or not----------
  function checkIfArrayIsUnique(myArray) {
    var countRight  = 0;
    for (var i = 0; i < myArray.length; i++) {
      countRight += new Set(myArray[i]).size;
    }
    return (countRight != 5*6);
  }

  //----------update productArray status----------
function removeItemOnce(arr, value) {
    var index = arr.indexOf(value);
    if (index > -1) {
      arr.splice(index, 1);
    }
    return arr;
  }

  console.log(splitArray());

似乎可以解决问题,但实际上 productArray 不是必须 30,此解决方案将花费大量时间尝试不重复组合。效率低

我相信他们有比我的想法更好的解决问题的其他解决方案

任何帮助将不胜感激。

【问题讨论】:

    标签: javascript arrays duplicates combinations


    【解决方案1】:

    我的方法是:只需将下一个数字放在随机选择的 array 中 - 当然,过滤掉那些已经包含下一个数字的数字。

    // the beginning dataset
    const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    
    // the size of the groups to be formed (must divide the
    // size of beginning dataset without a remainder)
    const ARR_LENGTH = 6
    
    // creating the array that will be filled randomly
    const getBaseArray = ({ data, arrLength }) => {
      const num = parseInt(data.length / arrLength, 10)
      return Array.from(Array(num), () => [])
    }
    
    // filter arrays that satisfy conditions
    const conditions = ({ subArr, val }) => {
      if (subArr.includes(val)) return false
      if (ARR_LENGTH <= subArr.length) return false
      return true
    }
    const getArraysFiltered = ({ val, arr }) => {
      return arr
        .map((e, i) => ({
          origIdx: i,
          subArr: e,
        }))
        .filter(({ subArr }) => conditions({ subArr, val }))
    }
    
    // select a random array from a list of arrays
    const getRandomArrIdx = ({ arr }) => {
      return Math.floor(Math.random() * arr.length)
    }
    
    // get the original array index from the filtered values
    const getArrIdx = ({ val, arr }) => {
      const filtered = getArraysFiltered({ val, arr })
      if (!filtered.length) return -1
    
      const randomArrIdx = getRandomArrIdx({ arr: filtered })
      return filtered[randomArrIdx].origIdx
    }
    
    const getFinalArr = ({ data }) => {
      // short circuit: if the data cannot be placed in
      // arrays evenly, then it's a mistake (based on
      // the current ruleset)
      if (data.length % ARR_LENGTH) return [false]
    
      // creating the array that will hold the numbers
      const arr = getBaseArray({ data, arrLength: ARR_LENGTH })
     
      let i = 0;
      for (i; i < data.length; i++) {
        const idx = getArrIdx({
          val: data[i],
          arr,
        })
        // if there's no place that the next number could be
        // placed, then break (prematurely), so the algorithm
        // can be restarted as early as possible
        if (idx === -1) break;
        arr[idx].push(data[i])
      }
    
      if (i < data.length) {
        // restart algorithm if we couldn't place
        // all the numbers in the dataset
        return getFinalArr({ data })
      } else {
        return arr
      }
    
    }
    
    // constructing the final array of arrays & logging them:
    console.log('res', getFinalArr({ data }).join(' '))
    console.log('res', getFinalArr({ data }).join(' '))
    console.log('res', getFinalArr({ data }).join(' '))
    console.log('res', getFinalArr({ data }).join(' '))

    我不知道它是否更有效,但我发现这个问题很有趣。

    现在,算法是

    • 分解成小的逻辑步骤
    • 易于理解
    • 根据需要轻松调整
    • 适用于所有大小的数据(如果要创建的组可以平均填充)

    【讨论】:

    • 非常感谢,太完美了~我还在学习Javascript。所以我会试着理解这个理论。
    最近更新 更多