nidhi sharma
nidhi sharma

Reputation: 103

Finding the range in the array of arrays

Here I have a function that finds the range of values of array if they are in sequence if they break then it simple return the element

if i've an array const array2 = [[1, 2],[1, 3],[1, 4],[3, 8],[3, 11],[6, 1],[6, 2]] then the output should be ['1,2-4', '3,8', '3,11', '6,1-2'] my function works fine for this type of array

but if i've an array that does not have the same format, for example, initially values are in sequence, then they aren't, and then they come back in sequence, the function fails.

const array = [[1, 2],[1, 3],[1, 4],[1, 5],[1, 7],[1, 9],[1, 12],[1, 13],[1, 14],[2, 5],[2, 6],[2, 7],[10, 2],[10, 8]];

it shows the output

['1,2-14', '1,7', '1,9', '1,12', '2,5-7', '7,6-7', '8,7', '8,9', '10,2', '10,8']

instead of this

['1,2-5', '1,7', '1,9', '1,12-14', '2,5-7', '7,6-7', '8,7', '8,9', '10,2', '10,8']]

here is the code link : https://codesandbox.io/s/hopeful-allen-3okc0p?file=/src/index.js:11-174

Upvotes: 0

Views: 155

Answers (2)

Peter Thoeny
Peter Thoeny

Reputation: 7616

You can do that with a .reduce() that filters the array and builds a new array:

const array = [[1, 2],[1, 3],[1, 4],[1, 5],[1, 7],[1, 9],[1, 12],[1, 13],[1, 14],[2, 5],[2, 6],[2, 7],[10, 2],[10, 8]];
let v0;
let v1;
let result = array.reduce((newArr, row) => {
  if(row[0] != v0 || row[1] != v1 + 1) {
    // non-consecutive number, so push to new array
    newArr.push(row[0] + ',' + row[1]);
  } else {
    let val = newArr[newArr.length - 1]; // get top array element
    if(val.match(/,\d+$/)) {  // first occurrence
      val += '-' + row[1];    // add number
    } else {
      val = val.replace(/-\d+$/, '-' + row[1]); // replace last number
    }
    newArr[newArr.length - 1] = val; // update last array element
  }
  v0 = row[0]; // remember value for next row
  v1 = row[1]; //  "
  return newArr;
}, []); // initialize new array to empty
console.log(result);

Output:

[
  "1,2-5",
  "1,7",
  "1,9",
  "1,12-14",
  "2,5-7",
  "10,2",
  "10,8"
]

Upvotes: 1

Layhout
Layhout

Reputation: 1580

const array0 = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 7], [1, 9], [1, 12], [1, 13], [1, 14], [2, 5], [2, 6], [2, 7], [10, 2], [10, 8]];

const array1 = [[1, 2],[10, 2],[1, 4],[1, 3],[1, 5],[1, 7],[1, 9],[1, 12],[1, 13],[1, 14],[2, 5],[2, 6],[2, 7],[10, 8]];

const array2 = [[1, 2],[1, 3],[1, 4],[3, 8],[3, 11],[6, 1],[6, 2]];

const array3 = [[1, 2],[1, 4],[1, 3],[1, 5],[1, 7],[1, 9],[2, 5],[2, 6],[2, 7],[10, 8]];

const createRange = arr => {
    let s = null, d = 0;

    return arr.sort((a, b) => a - b).reduce((p, c, i, arr) => {
        d++;
        if (!s) s = c;
        if (arr[i + 1] - s > d) {
            s === c ? p.push(s) : p.push(`${s}-${c}`);
            s = null;
            d = 0;
        }
        if (!arr[i + 1]) s === c ? p.push(s) : p.push(`${s}-${c}`);

        return p;
    }, []);
}

const findRangeInArr = arr => {
    return arr.reduce((p, c) => {
        const found = p.findIndex(p => p[0] === c[0]);
        if (found !== -1) p[found][1].push(c[1]);
        else p.push([c[0], [c[1]]]);

        return p;
    }, []).flatMap(a => createRange(a[1]).map(r => `${a[0]}, ${r}`)).sort((a, b) => Number(a.split(",")[0]) - Number(b.split(",")[0]));
}

console.log("arr0:", findRangeInArr(array0));
console.log("arr1:", findRangeInArr(array1));
console.log("arr2:", findRangeInArr(array2));
console.log("arr3:", findRangeInArr(array3));

Upvotes: 1

Related Questions