给定一组递增的整数:如何为每三个或更多连续整数返回一个范围?

时间:2017-08-16 14:32:00

标签: javascript arrays ruby

给定下面的整数数组(列表),我想提取每个整数,如果三个或更多整数连续上升,我想用" - "替换中间整数。代表一个范围。然后最后将值作为字符串返回。

例如,列表中的前7个整数:-6, -3, -2, -1, 0, 1, 3 将成为'-6,-3-1,3'
因为从-3到1有超过三个连续的整数。

最终,solution(list)应返回以下字符串:"-6,-3-1,3-5,7-11,14,15,17-20"

以其当前形式返回以下字符串:"-6,-3,-2,-1,0,1,3,4,5,7,8,9,10,11,14,15,17,18,19,20" 这只是将数组转换为字符串。

var list = [-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20];
solution(list);

function solution(list) {
    final = [];
    range = [];
    while (list.length > 0) {
        take = list.splice(0,1);
        range.push(take); 
        n = 1;
        while (take+n === list[0]) {
            a = list.splice(0,1); 
            range.push(a);
            n++;
        }
        if (range.length >= 3) {
            min = Math.min(range).toString();
            max = Math.max(range).toString();
            final.push(min + "-" + max); 
            range.length = 0;
        } else if (range.length === 2) {
            final.push(range[0].toString());
            final.push(range[1].toString());
            range.length = 0;
        } else if (range.length === 1) {
            final.push(range[0].toString());
            range.length = 0;
        }
    }
    return final.join(",");
}

但是,我能够在Ruby中成功获得所需的结果:

list = [-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]

def solution(list)
    final = []
    range = []
    while (list.length > 0) do
        take = list.shift
        range << take 
        n = 1
        while (take+n == list[0]) do
            a = list.slice!(0) 
            range << a
            n +=1
        end
        if (range.length >= 3)
            final << (range.min.to_s + "-" + range.max.to_s) 
            range = []
        elsif (range.length == 2)
            final << range[0]
            final << range[1]
            range = []
        elsif (range.length == 1)
            final << range[0].to_s
            range = []
        end
    end
    return final.join(",")
end

我在Ruby中的方法几乎与我的JavaScript相同。所以,如果我想知道是否有人可以:

1)解释为什么这种方法适用于Ruby,而不是Javascript。即使这是一个简单的语法错误,请随时通知我。

2)我怎样才能在JavaScript中提取整数并返回正确的范围?

非常感谢您的帮助!谢谢!

3 个答案:

答案 0 :(得分:5)

这是一个更好的红宝石解决方案:

list = [-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]

stringified = list.chunk_while{|a, b| a == b - 1}.map do |seq|
#                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the core of the solution
  if seq.length > 2 # long enough sequence
    "#{seq.first}-#{seq.last}"
  else
    seq
  end
end.join(', ')

stringified # => "-6, -3-1, 3-5, 7-11, 14, 15, 17-20"

这也应该是你的javascript实现的提示。尽可能分开关注。分块,字符串化,将序列转换为类似范围的字符串:这些都应该是单独的代码片段。如果他们并非全都纠结在一起,他们就更容易推理。

答案 1 :(得分:3)

在Javascript中,您可以使用三遍方法,首先获取分组范围,然后获取数组中的范围,然后加入整个数组。

var array = [-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20],
    result = array
        .reduce(function (r, a) {
            var last = r[r.length - 1];
            if (last && last[1] + 1 === a) {
                last[1] = a;
            } else {
                r.push([a, a]);
            }
            return r;
        }, [])
        .reduce(function (r, a) {
            return r.concat(a[0] === a[1] ? a[0] : a[1] - a[0] < 2 ? a : a.join('-'));
        }, [])
        .join();

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

答案 2 :(得分:2)

Splice返回一个数组,你必须从返回的数组中取出第一个项目

take = list.splice(0,1)[0];
  

另请注意,shifttake = list.shift())是此操作的更好选择。

Math.min不接受数组,您可以使用apply / call

的变通方法
Math.min.apply(null,range);
  

在ES6中,可以使用spread syntax

Math.min(...range)完成此操作

最好通过分配一个新数组来清除数组。

range = [];

我显然更喜欢@ninasholz的功能和声明方法这只是为了解释为什么我的代码不起作用

var list = [-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20];
console.log(solution(list));

function solution(list) {
  final = [];
  range = [];
  while (list.length > 0) {
         //splice returns array take first item
        take = list.splice(0,1)[0];
        range.push(take); 
        n = 1;
        while (take + n === list[0]) {
              a = list.splice(0,1)[0]; 
              range.push(a);
              n++;
        }
        console.log(range);
        if (range.length >= 3) {
        //Math.min doesnt accept arrays
           min = Math.min.apply(null,range);
           max = Math.max.apply(null,range);
           final.push(min + "-" + max); 
           range = [];
        } else if (range.length === 2) {
                  final.push(range[0]);
                  final.push(range[1]);
                  range = [];
        } else if (range.length === 1) {
                  final.push(range[0]);
                  range = [];
        }
  }
  return final.join(",");
}