Search code examples
javascriptmultidimensional-arrayecmascript-5

JavaScript Finding/Comparing and updating duplicate elements of metric/multi dimension array


I have a metric/multi dimension array like below

[
[a,b,c,d],
[d,a,c,b],
[a,d,b,a],
[c,c,d,a]
]

I am required to update my given metric and keep track of change in a such a way

  1. An element can repeat itself in one column only.

  2. An element can not occur in other columns if it has occurred in a column.

  3. If the above condition occur update the element by appending the column index to all its occurrence in a column.

In the above example element at index [1][1]('a' in row 2 and column 2) has occur in column 1. It and all its occurrence should update to 'a1'. Similarly 'd' and 'c' should update to 'd1' and 'c1' respectively.
In the next column Column 3, 'c', 'b', 'd' in column 3 should update to 'c2','b2','d2' because 'b' has occurred is column 2, similarly 'c' and 'd' has occurred before.
In next column Column 4 'd','b','a' will update to 'd4','b4','a4'.

Resulted metric will look like

[
[a,b, c3,d4],
[d,a2,c3,b4],
[a,d2,b3,a4],
[c,c2,d3,a4]
]

Keep track part we can keep track like

var dictionary = [{"updatedValue":"originalValue"},...]
var dictionary = [{"a2":"a"},{"d2","d"},{"c2","c"},{"c3":"c"},{"b3":"b"},{"d3":"d"},{"d4","d"},{"a4":"a"},{"b4","b"}];  

so far I have tried this

  var flatData = [
        ['a', 'b', 'c', 'd'],
        ['d', 'a', 'c', 'b'],
        ['a', 'd', 'b', 'a'],
        ['c', 'c', 'd', 'a'],
    ];
    for (var i = 0; i < flatData.length; i++) {
        for (var j = 0; j < flatData[i].length; j++) {
            var element = flatData[i][j];
            for (var k = 0; k < flatData.length; k++) {
                for (var l = 0; l < flatData[k].length; l++) {
                    if (j != l) {
                        if (element == flatData[k][l]) {
                            flatData[k][l] = flatData[k][l] + l;
                        }
                    }
                }
            }
        }
    }
    console.log(JSON.stringify(flatData));


Solution

  • Solution uses a Map(could be plain object also) where first time a value is encountered a new entry is created that has an object {col: firstColIndexFound, count:0}.

    Next time same value is encountered it checks stored column index and if different updates the count and creates a new value

    const data = [
      ['a', 'b', 'c', 'd'],
      ['d', 'a', 'c', 'b'],
      ['a', 'd', 'b', 'a'],
      ['c', 'c', 'd', 'a']
    ];
    
    
    const dict = {};
    const map = new Map();
    
    for (let c = 0; c < data[0].length; c++) { // c for colIndex
      for (let r = 0; r < data.length; r++) { // r for rowIndex
        const el = data[r][c];
        if (!map.has(el)) {
          // first time found create new entry
          map.set(el, {col: c, count: 0});
        }
        const entry = map.get(el);
        // if column index different than first column found update value
        if (c !== entry.col) {
          entry.count++;
          const nVal = el + entry.count;
          dict[nVal] = el;
          data[r][c] = nVal;
        }
      }
    }
    
    console.log(JSON.stringify(data))
    console.log(dict)
    .as-console-wrapper {
      max-height: 100%!important;
      top: 0;
    }