Simon Dean
Simon Dean

Reputation: 237

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

In the below function I am attempting to get an output which resembles this:

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

I can see that the problem I have embedded is that I am always adding the temp array with a push to the functions return, as a result, all of the individual numbers apart from the last number in the for each function are being pushed into the target array with the array object also.

I feel as though I need a further conditonal check but for the life of me I am unable to come up with solution which works.

Any suggestions would be much appreciated.

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); 

Upvotes: 1

Views: 96

Answers (4)

Ajai Maxwel
Ajai Maxwel

Reputation: 19

I hope the below one is quite simple;

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 ]

Upvotes: 0

Terry Lennox
Terry Lennox

Reputation: 30685

And another approach, just for fun:

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);

Upvotes: 0

Terry Lennox
Terry Lennox

Reputation: 30685

This should work (using 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);

Upvotes: 1

Taki
Taki

Reputation: 17654

i would make a deduped copy and .map() it to transform the values into arrays containing values from the original ( sorted ) array that you get using a .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);

Upvotes: 2

Related Questions