0

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

2 Answers 2

1

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"
]
Sign up to request clarification or add additional context in comments.

Comments

1

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));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.