javascriptjqueryarraysfilter

Javascript array, finding duplicates then return the locations in new array;


I'am trying to build a function (preferably Javascript but JQuery is Ok) that searches through a vase array of exam results checking for duplicates scores. Using filter I have managed to return that the scores (2,4,5) have been achieved more than once.

    exam_scores[0] = [1, 2, 3, 7, 2, 4, 5, 4, 5, 7];
 
    // Returns exams_scores[0] That Are Duplicated;
    const duplicates = exams_scores[0].filter((item, index) => exams_scores[0].indexOf(item) !== index);
 
    console.log(duplicates); // Output: [2, 4, 5]`

From here (and this is what I am stuck on) I want to return a new two dimensional array with the indexes as they appear in the exam_scores array;

Thus in the example, it would return this:

result[0] = [1,4];  // 2 is found at index (1,4);
result[1] = [5,7];  // 4 is found at index (5,7);
result[2] = [6,8];  // 5 is found at index (6,8);

I know with the few lines of code thus far I could use a for - loop but this will have over 1500 names.

I have looked at filter but not sure what is the best was to go about it.

Thanks.

    exam = [1, 2, 3, 7, 2, 4, 5, 4, 5, 7];
    
    // Returns Numbers That Are Duplicated;
    const duplicates = exam.filter((item, index) => exam.indexOf(item) !== index);
    console.log(duplicates+"<br/>"); // Output: [2, 4, 5]
 
    // I then want to return the index of each duplication in a new array as outlined above.

Solution

  • I'd map the initial array to a series of pairs of the value and its index, and then accumulate them to an object that maps the value to an array of indexes. Then, you can filter out the values that only have on index.

    Put it all together, and you'll get:

    const exam_scores = [];
    exam_scores[0] = [1, 2, 3, 7, 2, 4, 5, 4, 5, 7];
    
    const result =
        Object.fromEntries(Object.entries(exam_scores[0]
            .map((element, index) => [element, index])
            .reduce((accumulator, item) => {
                accumulator[item[0]] ? 
                    accumulator[item[0]].push(item[1]) : 
                    accumulator[item[0]] = [item[1]];
                return accumulator;
                }, {}
            )
        ).filter(pair => pair[1].length > 1));
    
    console.log(result);