3

if I have a js array like below, is there a simple way to re-group the array values by range, the logic is based on the range step, the range step is 1, so if the array values are continuous increased by 1, then it should be write like "1-3", otherwise it should be break to another group, thanks a lot!

var list = ["1", "2", "3", "5", "6", "9", "12", "13", "14", "15", "16"]

function(list) {

    // * some function here //

    return ["1-3", "5-6", "9", "12-16"]
}
3
  • 1
    And what's the logic for those ranges? It looks like modulus of three or something, but how does "12-16" end up in the last one? Commented Nov 4, 2016 at 21:04
  • Hi adeneo, sorry I forgot to point this, the logic is based on the range step, the range step is 1, so if the array values are continuous increased by 1, then it should be write like "1-3". thanks a lot! Commented Nov 4, 2016 at 21:08
  • 1
    @BobChou Consider updating Question with description of logic. Commented Nov 4, 2016 at 21:10

2 Answers 2

5

You could use Array#reduce for it.

var array = ["1", "2", "3", "5", "6", "9", "12", "13", "14", "15", "16"],
    result = array.reduce(function (r, a, i, aa) {
        r.push(!i || aa[i - 1] - a + 1 ? a : r.pop().split('-')[0] + '-' + a);
        return r;
    }, []);

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

Sign up to request clarification or add additional context in comments.

Comments

1

Here is not as compact as @nina-scholz's version, but 70% faster. It also allows creating only "non-redundant" ranges (ranges with minimum difference of 2 or greater, which might speed up decoding)

function getRanges(array, minRange, sort)
{
  if (sort)
    array = new Float64Array(array).sort();

  let min = array[0],
      max = min,
      result = [];

  minRange = minRange ? 1 : 0;
  for(let i = 1, c = array.length + 1; i < c; i++)
  {
    const id = array[i];
    if (max == id - 1)
    {
      max = id + ""; // + converting to string
      continue;
    }
    if (max-min > minRange)
      result.push(min + "-" + max);
    else if (min != max)
      result.push(min, max);
    else
      result.push(min);

    min = max = id + ""; // + converting to string
  }
  return result;
}


//examples
var array = ["1", "2", "3", "5", "6", "9", "12", "13", "14", "15", "16"];
console.log(JSON.stringify(array));

console.log("ranges with minimum diference of 1:", JSON.stringify(getRanges(array)));
console.log("ranges with minimum diference of 2:", JSON.stringify(getRanges(array, true)));

array.sort(()=>.5-Math.random());//randomize array
console.log(JSON.stringify(array));
console.log("ranges with minimum diference of 1 sorted:", JSON.stringify(getRanges(array, false, true)));
console.log("ranges with minimum diference of 2 sorted:", JSON.stringify(getRanges(array, true, true)));
console.log("ranges with minimum diference of 1 unsorted:", JSON.stringify(getRanges(array)));
.as-console-wrapper { max-height: 100% !important; top: 0; }

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.