Home > Enterprise >  How can I get a two dimensional array in this format?
How can I get a two dimensional array in this format?

Time:05-06

My input array :

["red", "blue", "blue", "blue", "blue", "red", "blue", "blue", "blue", "blue", "blue", "blue", "red", "red", "red", "red", "red", "blue", "red", "red"]

I got an array in this format.

    [
      ["red", "blue", "red", "blue", "red", "blue", "red", "", "", "", "", "", "", "", "", "", "", "", "", ""],
      ["red","blue","","","","","","","","","","","","","","","","","",""],
      ["red","blue","","","","","","","","","","","","","","","","","",""],
      ["red","blue","","","","","","","","","","","","","","","","","",""],
      ["red","blue","","","","","","","","","","","","","","","","","",""],
      ["","blue","","","","","","","","","","","","","","","","","",""],
    ]

And i want the result array in this format

    [
       ["red", "blue", "red", "blue", "red", "blue", "red", "", "", "", "", "", "", "", 
         "", "", "", "", "", ""],
       ["","blue","","blue","red","","red","","","","","","","","","","","","",""],
       ["","blue","","blue","red","","","","","","","","","","","","","","",""],
       ["","blue","","blue","red","","","","","","","","","","","","","","",""],
       ["","","","blue","red","","","","","","","","","","","","","","",""],
       ["","","","blue","","","","","","","","","","","","","","","",""],
     ]

enter image description here

And this is my code:

const findArrayColorDuplicate = function (array) {
  const dupIndexes = new Set();
  const dupValues = new Set();
  for (let i = 0; i < array.length - 1; i  ) {
    if (array[i] === array[i   1]) {
      dupIndexes.add(i   1)
      dupValues.add({ index: i   1, number: array[i   1] });
    }
  }
  return { index: [...dupIndexes], value: [...dupValues] }
}
const formatArrayDuplicate = function (arr) {
  const results_history = []
  const arr_1 = ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', ''];
  const arr_2 = ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', ''];
  const arr_3 = ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', ''];
  const arr_4 = ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', ''];
  const arr_5 = ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', ''];
  const arr_6 = ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', ''];

  // Find array duplicate in range
  const dupArray_1 = findArrayColorDuplicate(arr)
  // *************************** Row 1 ***************************
  for (let i = 0; i < dupArray_1.index.length; i  ) {
    for (let j = 0; j < arr.length; j  ) {
      if (j === dupArray_1.index[i]) {
        arr_1[j] = arr[j]
        arr[j] = ''
      }
    }
    const $dup = dupArray_1.value.find(value => value.index ===
      dupArray_1.index[i])
    arr_2[$dup.index] = $dup.number
  }


  const arr_row_1 = arr.filter(value => value !== 0)
  for (let i = 0; i < 20; i  ) {
    if (arr_row_1.length < 20)
      arr_row_1.push(0)
  }
  // *************************** Row 2 ***************************
  const arr_row_2 = ['', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', '', '', '']
  for (let i = 0; i < dupArray_1.index.length; i  ) {
    const t = arr_row_1.findIndex(value => value === dupArray_1.value[i].number)
    arr_row_2[t] = dupArray_1.value[i].number
  }


  // *************************** Row 3 ***************************
  const dupArray_2 = findArrayColorDuplicate(arr_2)
  const arr_row_3 = ['', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', '', '', '']
  for (let i = 0; i < dupArray_2.index.length; i  ) {
    const t = arr_row_2.findIndex(value => value === dupArray_2.value[i].number)
    arr_row_3[t] = dupArray_2.value[i].number

    const $dup = dupArray_2.value.find(value => value.index ===
      dupArray_2.index[i])
    arr_3[$dup.index] = $dup.number
  }

  // *************************** Row 4 ***************************
  const dupArray_3 = findArrayColorDuplicate(arr_3)
  const arr_row_4 = ['', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', '', '', '']
  for (let i = 0; i < dupArray_3.index.length; i  ) {
    const t = arr_row_3.findIndex(value => value === dupArray_3.value[i].number)
    arr_row_4[t] = dupArray_3.value[i].number

    const $dup = dupArray_3.value.find(value => value.index ===
      dupArray_3.index[i])
    arr_4[$dup.index] = $dup.number
  }

  // *************************** Row 4 ***************************
  const dupArray_4 = findArrayColorDuplicate(arr_4)
  const arr_row_5 = ['', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', '', '', '']
  for (let i = 0; i < dupArray_4.index.length; i  ) {
    const t = arr_row_4.findIndex(value => value === dupArray_4.value[i].number)
    arr_row_5[t] = dupArray_4.value[i].number

    const $dup = dupArray_4.value.find(value => value.index ===
      dupArray_4.index[i])
    arr_5[$dup.index] = $dup.number
  }

  // *************************** Row 4 ***************************
  const dupArray_5 = findArrayColorDuplicate(arr_5)
  const arr_row_6 = ['', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', '', '', '']
  for (let i = 0; i < dupArray_5.index.length; i  ) {
    const t = arr_row_5.findIndex(value => value === dupArray_5.value[i].number)
    arr_row_6[t] = dupArray_5.value[i].number

    const $dup = dupArray_5.value.find(value => value.index ===
      dupArray_5.index[i])
    arr_6[$dup.index] = $dup.number
  }

  results_history[0] = arr_row_1;
  results_history[1] = arr_row_2;
  results_history[3] = arr_row_3;
  results_history[4] = arr_row_4;
  results_history[5] = arr_row_5;
  results_history[6] = arr_row_6;
  return results_history;
}

const arr = ["red", "blue", "blue", "blue", "blue", "red", "blue", "blue",
  "blue", "blue", "blue", "blue", "red", "red", "red", "red", "red", "blue", "red",
  "red"];
formatArrayDuplicate(arr);

CodePudding user response:

Presented below is one possible way to achieve the desired objective.

Code Snippet

// helper method
const myMerge = (c, e, r) => {
  // initialize result "row"
  const res = [];
  
  // iterate upto column "c"
  for (let i = 0; i < c; i  ) {
    // populate each elt in "res"
    res[i] = (
      r && r?.length && i < r.length
      ? r[i]
      : '___'   // replace this with ""
    );
  };
  
  // populate the last elt in "res"
  res[c] = e;
  
  return res;
};

// assignment is done
const doMyAssignmentWork = arr => {
  // result 2d array, initialized with 0-th elt
  const res2d = [[arr[0]]];
  
  // markers for row & col in res2d
  let col = 0, row = 0;
  
  // loop through the input array
  for (let i = 1; i < arr.length; i  ) {
    // note the previous & current element
    const prev = arr[i-1], elt = arr[i];
    
    // if previous & current match (ie, dupe)
    if (prev === elt) {
      row  ;
      res2d[row] = myMerge(col, elt, res2d[row]);
    } else {
      // previous & current are different
      col  ;
      row = 0;
      res2d[row][col] = elt;
    }
  };
  return res2d;
};

const myArray = [
  'red', 'blue', 'red', 'red', 'blue', 'red', 'blue', 'blue', 'blue',
  'blue', 'red', 'red', 'blue', 'red', 'blue', 'blue', 'red', 'red',
  'red', 'red'
];

console.log(
  'given input: ',
  JSON.stringify(myArray),
  '\n\ndesired result:\n',
  doMyAssignmentWork(myArray)
  .map(x => x.join())
);
.as-console-wrapper { max-height: 100% !important; top: 0 }

Explanation

Inline comments added to the snippet above.

PS: Please replace the '___' with empty-string "". The former has been used merely for the result to be displayed in snippet in a relatively easier to verify manner.

CodePudding user response:

This is a potential answer using a recursive function. Those are quite powerful! I have added some css to style the output to make it easier to visualize.

const myList = ["red", "blue", "blue", "blue", "blue", "red", "blue", "blue", "blue", "blue", "blue", "blue", "red", "red", "red", "red", "red", "blue", "red", "red"];
const target = document.getElementById('target');


const out = ColorSplit(myList, [
  []
], 0, 0);

function ColorSplit(input, output, index, count) {
  //If the value of the input is the same as the previous value, we want to add it to the currently selected array - this is determined by the index varaible.
  if (count == 0 || input[count - 1] == input[count])
    output[index].push(input[count]);
  //If the previous value in the input is different from our current value, we want to make a new arry and add it to that. We also increment the index, as this move the pointer to the array we are currently focused on.
  else {
    index  = 1;
    output[index] = [input[count]];
  }
  
  //This is where we do the recursiveness. If we have not finished going through the entire array, we call ColorSplit again. Else we return.
  return count < input.length - 1 ? ColorSplit(input, output, index, count  = 1) : output;
}

//Displaying the results -- not part of the answer
for (var x = 0; x < out.length; x  ) {
  let comp = "<div>";
  out[x].forEach(i => {
    comp  = `<span >${i}</span>`;
  });
  comp  = "</div>";
  target.innerHTML  = comp;
}
#target {
  display: inline-flex;
  flex-direction: row;
}

#target div {
  display: inline-flex;
  flex-direction: column;
}

span {
  background-color: grey;
  width: 2em;
  height: 2em;
  display: inline-flex;
  text-align: center;
  justify-content: center;
}

.red {
  background-color: red;
}

.blue {
  background-color: blue;
}
<div id="target"></div>

CodePudding user response:

We can do this atop some reusable functions. group, pad, and transpose are all genuinely useful function for many projects. With them, we can create regroup fairly simply:

const group = (xs, idx = xs .findIndex (x => x !== xs [0])) =>
  xs .length == 0 ? [] : idx < 0 ? [xs] : [xs .slice (0, idx), ... group (xs .slice (idx))]

const pad = (n, v) => (xs) => 
  [...xs, ...Array (Math .max (n - xs.length, 0)) .fill (v)]

const transpose = (xs) => 
  [... xs [0]] .map ((_, i) => [... xs] .map (r => r [i]))

const regroup = (xs) => {
  const grouped = group (xs)
  const length = Math .max (... grouped .map (g => g.length))
  const ys = grouped .map (pad (length, ''))
  return transpose (ys) .map (pad (xs .length, ''))
}

const input = ["red", "blue", "blue", "blue", "blue", "red", "blue", "blue", "blue", "blue", "blue", "blue", "red", "red", "red", "red", "red", "blue", "red", "red"]

console .log (regroup (input))
.as-console-wrapper {max-height: 100% !important; top: 0}

group recursively takes an array and breaks it into sub-arrays of equal sequential values. So your original would become

[
  ["red"],
  ["blue", "blue", "blue", "blue"],
  ["red"], 
  ["blue", "blue", "blue", "blue", "blue", "blue"],
  ["red", "red", "red", "red", "red"],
  ["blue"], 
  ["red", "red"]
]

But these ragged arrays are not so easy to work with, so we use pad to fill them out to the length of the longest one, yielding:

[
  ["red",  "",     "",     "",     "",     ""    ], 
  ["blue", "blue", "blue", "blue", "",     ""    ], 
  ["red",  "",     "",     "",     "",     ""    ], 
  ["blue", "blue", "blue", "blue", "blue", "blue"],
  ["red",  "red",  "red",  "red",  "red",  ""    ], 
  ["blue", "",     "",     "",     "",     ""    ], 
  ["red", "red",   "",     "",     "",     ""    ]
]

Now we want to flip this matrix over its main diagonal. This is called transposition, and we use a simple transpose function to do this, yielding:

[
  ["red", "blue", "red", "blue", "red", "blue", "red"],
  ["",    "blue", "",    "blue", "red", "",     "red"],
  ["",    "blue", "",    "blue", "red", "",     ""   ],
  ["",    "blue", "",    "blue", "red", "",     ""   ], 
  ["",    "",     "",    "blue", "red", "",     ""   ], 
  ["",    "",     "",    "blue", "",    "",     ""   ]
]

And now the only thing left to do is to pad these resulting rows out to the length of the original input, which we do again by mapping pad over the results, with the length of the original output. (That's a fairly strange format to my mind, and if wasn't for a class, I would ask if all those trailing empty strings actually help something.)

Of these, the only tricky function is group, which finds the index of the first element which is different from the initial element in the array, splits that off into a new subarray, then recurs on the resulting array. If your course has not yet reached recursion, then you should probably look to see if you can do this with imperative loops instead of recursion.

If you have questions about these functions, feel free to ask in the comments.

  • Related