给定下面的整数数组(列表),我想提取每个整数,如果三个或更多整数连续上升,我想用" - "替换中间整数。代表一个范围。然后最后将值作为字符串返回。
例如,列表中的前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中提取整数并返回正确的范围?
非常感谢您的帮助!谢谢!
答案 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];
另请注意,shift(
take = 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(",");
}