2

I'm wrapping my head around the following logic, but I'm still missing something.

Given an Array like const testArr = ["F", "F", "C", "C", "F", "C", "F"].

The result array should look like ["F", "F", ["C", "C"], "F", ["C"], "F"].

The code I came up until now looks like this:

const grouping = (arr) => {
  const result = [];
  arr.forEach((item, index) => {
    if (item === "C") {
      const subArr = new Array();
      subArr.push(item);
      if (arr[index + 1] !== "C") {
        result.push(subArr);
      }
    } else {
      result.push(item);
    }
  });
  return result;
};

console.log(grouping(testArr));

This prints currently the result:

["F", "F", ["C"], "F", ["C"], "F"]

I appreciate your hints :-)

trincot
  • 317,000
  • 35
  • 244
  • 286

6 Answers6

3

You could use a while loop with a temporary index to achieve your expected result

Below is the small modifed from your current solution (change to for loop and use while for condition checking)

const testArr = ["F", "F", "C", "C", "F", "C", "F"]

const grouping = (arr) => {
  const result = []
  for (let index = 0; index < arr.length; index++) {
    if (arr[index] === "C") {
      const subArr = [arr[index]]
      let tempIndex = index + 1
      while (arr[tempIndex] === "C") {
        subArr.push(arr[tempIndex])
        index = tempIndex
        tempIndex++
      }
      result.push(subArr)
    } else {
      result.push(arr[index])
    }
  }

  return result
}

console.log(grouping(testArr))
hgb123
  • 13,869
  • 3
  • 20
  • 38
1

I think I'd do it like this, see comments:

const grouping = arr => {
    const result = [];
    let currentSub = null;
    for (const value of arr) {
        // Is it the special value?
        if (value === "C") {
            // Yes, do we have an active array?
            if (!currentSub) {
                // No, create one and push it
                currentSub = [];
                result.push(currentSub);
            }
            // Add to the active array
            currentSub.push(value)
        } else {
            // Not special, forget active array and push
            currentSub = null;
            result.push(value);
        }
    }
    return result;
};

Live Example:

const testArr = ["F", "F", "C", "C", "F", "C", "F"]

const grouping = arr => {
    const result = [];
    let currentSub = null;
    for (const value of arr) {
        // Is it the special value?
        if (value === "C") {
            // Yes, do we have an active array?
            if (!currentSub) {
                // No, create one and push it
                currentSub = [];
                result.push(currentSub);
            }
            // Add to the active array
            currentSub.push(value)
        } else {
            // Not special, forget active array and push
            currentSub = null;
            result.push(value);
        }
    }
    return result;
};

console.log(grouping(testArr));
.as-console-wrapper {
    max-height: 100% !important;
}

If you prefer a forEach to for-of, it's almost identical:

const testArr = ["F", "F", "C", "C", "F", "C", "F"]

const grouping = arr => {
    const result = [];
    let currentSub = null;
    arr.forEach(value => {
        // Is it the special value?
        if (value === "C") {
            // Yes, do we have an active array?
            if (!currentSub) {
                // No, create one and push it
                currentSub = [];
                result.push(currentSub);
            }
            // Add to the active array
            currentSub.push(value)
        } else {
            // Not special, forget active array and push
            currentSub = null;
            result.push(value);
        }
    });
    return result;
};

console.log(grouping(testArr));
.as-console-wrapper {
    max-height: 100% !important;
}

Side note: In general, avoid new Array(). To create a blank array, just use []. To create an array with entries, use [value1, value2] etc. You can use new Array(x) (or just Array(x)) to create a sparse array with the length x, but that's usually only useful when you're about to use fill on it to fill it with the same value in each entry.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

I would use a temp array for storing the 'special' value, and I would reset it anytime I encounter a different value.

const grouping = (arr) => {
  const result = []
  let tempC = []
  
  arr.forEach(letter => {
    if (letter === 'C') {
       tempC.push('C')         // Append the special letter to its temp array
    } else {
       if (tempC.length > 0) {
         result.push(tempC)    // If the previus iteration had a 'C', push the array in result
       }
       tempC = []              // Reset the tempC collector
       result.push(letter)     // Add the 'not special' letter to the result
    }
  })
  return result
}
gbalduzzi
  • 9,356
  • 28
  • 58
1

const testArr = ["F", "F", "C", "C", "F", "C", "F"];
const result = testArr.reduce((acc, val) => {
    if (val === "C") {
        Array.isArray(acc[acc.length - 1]) ? acc[acc.length - 1].push(val) : acc.push([val]);
    } else {
        acc.push(val);
    }

    return acc;
}, []);

console.log(result);
Nikita Madeev
  • 4,284
  • 9
  • 20
1

This is an approach using the function Array.prototype.reduce which is DRY.

const testArr = ["F", "F", "C", "C", "F", "C", "F"];
const {result} = testArr.reduce((a, e) => {
  if (e === a.target) (a.current || (a.current = [])).push(e);
  else {
    if (a.current) a.result.push(a.current), a.current = undefined;   
    a.result.push(e);
  }
  
  return a;
}, {result: [], current: undefined, target: "C"});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Ele
  • 33,468
  • 7
  • 37
  • 75
0

void groupElements(int arr[], int n) 
{ 
    // Initialize all elements as not visited 
    bool *visited = new bool[n]; 
    for (int i=0; i<n; i++) 
        visited[i] = false; 
  
    // Traverse all elements 
    for (int i=0; i<n; i++) 
    { 
        // Check if this is first occurrence 
        if (!visited[i]) 
        { 
            // If yes, print it and all subsequent occurrences 
            cout << arr[i] << " "; 
            for (int j=i+1; j<n; j++) 
            { 
                if (arr[i] == arr[j]) 
                { 
                    cout << arr[i] << " "; 
                    visited[j] = true; 
                } 
            } 
        } 
    } 
  
    delete [] visited;   
}