BASIC Javascript 数组函数,问题已知但我无法理解解决方案

BASIC Javascript array function, issue is known but I cannot fathom a solution

在下面的函数中,我试图获得类似这样的输出:

[[1,1,1,1],[2,2,2], 4,5,10,[20,20], 391, 392,591].

我可以看到我嵌入的问题是我总是添加临时数组并推送到函数 return,结果,除了最后一个数字之外的所有单独数字每个函数的 for each 函数也与数组对象一起被推入目标数组。

我觉得好像我需要进一步的条件检查,但对于我来说,我无法想出有效的解决方案。

如有任何建议,我们将不胜感激。

const sortme = (unsortedArr)=> {

let tempArr = []; 

let outputArr = []; 

const reorderedArr = unsortedArr.sort((a,b) => a-b); 

reorderedArr.forEach((number, i) => {

    if ((i === 0) || (reorderedArr[i] === reorderedArr[i-1])) {
    tempArr.push(number);  
    }

    else {     
    outputArr.push(tempArr);
    tempArr = [];
    tempArr.push(number); 
}  
})

outputArr.push(tempArr[0]);
    return outputArr; 
}

const unsortedArr = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20]; 

sortme(unsortedArr); 

我会制作一个去重副本,然后 .map() 它将值转换为数组,其中包含您使用 .forEach 获得的原始(已排序)数组中的值:

const unsortedArr = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];

const sortMe = (arr) => {
  arr = arr.sort((a, b) => a - b);
  
  // a short way to dedupe an array
  // results in : 1, 2, 4, 5, 10, 20, 391, 392, 591
  let dedupe = [...new Set(arr)]; 
  let tmpArr;

  return dedupe.map(e => {
    tmpArr = []; // empty tmpArr on each iteration
    
    // for each element of the deduped array, look for matching elements in the original one and push them in the tmpArr
    arr.forEach(a => {
      if (a === e) 
        tmpArr.push(e);
    })
    
    if(tmpArr.length === 1)
      return tmpArr[0]; // in case you have [4] , just return the 4
    else
      return tmpArr; // in case you have [1,1,1,1]
    
    // shorthand for the if/else above
    // return tmpArr.length === 1 ? tmpArr[0] : tmpArr;
  });
}

const result = sortMe(unsortedArr);

console.log(result);

这应该有效(使用 reduce):

 
const unsortedArr = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];

let lastValue = null;
var newArr = unsortedArr.sort((a,b) => a-b).reduce((acc, value) => {

    if (acc.length == 0 || ((acc.length > 0 || !acc[acc.length-1].length) && lastValue !== value)) {
        acc.push(value);
    } else if (acc.length > 0 && lastValue === value) {
        acc[acc.length-1] = (acc[acc.length-1].length ? acc[acc.length-1].concat([value]): [value, value]);
    } 
    
    lastValue = value;
    return acc;
}, []);


console.log(newArr);

另一种方法,仅供娱乐:

const unsortedArr = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];

var arr = unsortedArr.sort((a,b) => a-b).reduce((acc, value) => {
    if (acc.length > 0 && acc[acc.length-1].includes(value)) {
        acc[acc.length-1].push(value);
    } else {
        acc.push([value])
    }
    return acc;
}, []).map((v) => v.length > 1 ? v: v[0]);

console.log(arr);

希望下面的比较简单;

function findSame(pos, sortedArr){
    for(let i =pos; i<sortedArr.length; i++){
        if(sortedArr[i] !== sortedArr[pos]){
            return i
        }
    }
}

function clubSameNumbers(unsortedArr){
    let sortedArr = unsortedArr.sort((a,b)=>a-b) 
    //[ 1, 1, 1, 1, 2, 2, 2, 4, 5, 10, 20, 20, 391, 392, 591 ]
    let result = [] 
    for(let i = 0; i < sortedArr.length; i = end){
        let start = i
        var end = findSame(i, sortedArr)
        let arr = sortedArr.slice(i, end)
        arr.length > 1 ? result.push(arr) : result.push(...arr)         
    }
    return result
}


console.log(clubSameNumbers([1,2,4,591,392,391,2,5,10,2,1,1,1,20,20]))
//[ [ 1, 1, 1, 1 ], [ 2, 2, 2 ], 4, 5, 10, [ 20, 20 ], 391, 392, 591 ]