在一个数字序列中,如何计算一个数字出现多少次,即该值恰好比前一个数字的值小一?
How does one, within a sequence of digits, count how many times a digit appears thats value is exactly one less than the previous digit's one?
代码:
function OneDecremented(num) {
num = num.toString()
var count = 0
for(i = 1; i < num.length; i++) {
if(num[i - 1] - num[i] === 1){
count++
}
}
return count
}
console.log(OneDecremented(9876541110))
所以我很难理解两件事:
- i和num[i]有什么区别
- 我不明白 if 语句中的计算是如何进行的,有人可以分解一下吗?
抱歉,如果这些问题听起来太傻了,我是 JS 的新手,无法真正理解算术计算。谢谢你的时间。
what's the difference between i and num[i]
i
是迭代键,即 0、1、2 等,因为字符串化数字中有尽可能多的字符。 num[i]
是字符串中索引 i
处的字符,即 num[i]
其中 i
是 0 == 9
(字符串中索引 0 处的字符).
I don't understand how the calculation is happening inside the if statement, could someone break it down?
表示:如果计算字符串索引i-1
处的数字,减去当前正在考虑的数字(字符串中索引i
处)减去1,则递增count
.
实际用到的数字一步一步来:
- 9 - 没有前一个字符;计算 (undefined - 9) 不等于 1
- 8 - 前一个字符是 9; (9 - 8) == 1;递增
count
- 7 - 同上
- 6 - 同上
- 5 - 同上
- 4 - 同上
- 1 - 前一个字符是 4;计算 (4 - 1) 不等于 1
- 1 - 前一个字符为 1;计算 (1 - 1) 不等于 1
- 1 - 同上
- 0 - 前一个字符为 1; (1 - 0) == 1;递增
count
该代码写得不好有几个原因,但最重要的是,它泄漏了全局的 i
引用,所以,让我们从一个更好的版本开始:
function OneDecremented(num) {
var str = num.toString();
var count = 0;
for(var i = 1; i < str.length; i++) {
if(str[i - 1] - str[i] === 1)
count++;
}
return count;
}
字符串,在现代JS中,可以像数组一样访问,索引returns是index
位置的char:
if(str[i - 1] - str[i] === 1)
// is the same as
if ((str.charAt(i - 1) - str.charAt(i)) === 1)
一旦检索到每个字符,代码就会执行隐式的“字符到数字”转换,这要归功于 -
运算符,但如果它是 +
相反,它会将两个字符连接成字符串(所以,要小心)。
明确总是更好,但如果您知道 -
的工作原理,它就可以完成这项任务。
循环从 1
开始,它检查 i - 1
处的字符,即第一次迭代中索引 0
处的字符,减去当前字符,是1
,表示当前字符 比前一个字符少 。
在这种情况下,计数器会求和。
Andrea 和 Mitya 已经搞定了。
下一步可能是切换到 first class based approach like using a specific Array
method such as reduce
。
这种方法如果实施得当,通常会改进 readability/maintainability 代码并实现更好的代码重用。
对于 OP 提供的示例,可以编写两个函数,即获取计数的实际方法和上面提到的第一个 class reducer 功能。由于 reduce
是处理数组的标准方式,因此 reducer/callback 的参数优先级也已明确指定 ...
[/* ... */].reduce(function(accumulator, currentValue, currentIndex, currentlyProcessedArray) {
// implement reducer/aggregation/accumulator logic here.
// the return value serves as the
// new `accumulator` value within
// the next iteration step.
// thus, always return something! ... e.g ...
return (accumulator + currentValue);
});
function aggregatePrecursorAndDecrementedSuccessorCount(count, char, idx, arr) {
const precursorValue = Number(arr[idx - 1]);
const incrementedCurrentValue = (Number(char) + 1);
const isValidCount = (precursorValue === incrementedCurrentValue);
return (count + (isValidCount ? 1 : 0));
//return (count + Number(isValidCount)); // cast boolean value to either 1 or 0.
}
function getPrecursorAndDecrementedSuccessorCount(int) {
return String(int) // - assure/typecast always a/into string value.
.split('') // - split string value into an array of single characters.
.reduce(aggregatePrecursorAndDecrementedSuccessorCount, 0);
}
console.log(getPrecursorAndDecrementedSuccessorCount(9876541110));
.as-console-wrapper { min-height: 100%!important; top: 0; }
代码:
function OneDecremented(num) {
num = num.toString()
var count = 0
for(i = 1; i < num.length; i++) {
if(num[i - 1] - num[i] === 1){
count++
}
}
return count
}
console.log(OneDecremented(9876541110))
所以我很难理解两件事:
- i和num[i]有什么区别
- 我不明白 if 语句中的计算是如何进行的,有人可以分解一下吗?
抱歉,如果这些问题听起来太傻了,我是 JS 的新手,无法真正理解算术计算。谢谢你的时间。
what's the difference between i and num[i]
i
是迭代键,即 0、1、2 等,因为字符串化数字中有尽可能多的字符。 num[i]
是字符串中索引 i
处的字符,即 num[i]
其中 i
是 0 == 9
(字符串中索引 0 处的字符).
I don't understand how the calculation is happening inside the if statement, could someone break it down?
表示:如果计算字符串索引i-1
处的数字,减去当前正在考虑的数字(字符串中索引i
处)减去1,则递增count
.
实际用到的数字一步一步来:
- 9 - 没有前一个字符;计算 (undefined - 9) 不等于 1
- 8 - 前一个字符是 9; (9 - 8) == 1;递增
count
- 7 - 同上
- 6 - 同上
- 5 - 同上
- 4 - 同上
- 1 - 前一个字符是 4;计算 (4 - 1) 不等于 1
- 1 - 前一个字符为 1;计算 (1 - 1) 不等于 1
- 1 - 同上
- 0 - 前一个字符为 1; (1 - 0) == 1;递增
count
该代码写得不好有几个原因,但最重要的是,它泄漏了全局的 i
引用,所以,让我们从一个更好的版本开始:
function OneDecremented(num) {
var str = num.toString();
var count = 0;
for(var i = 1; i < str.length; i++) {
if(str[i - 1] - str[i] === 1)
count++;
}
return count;
}
字符串,在现代JS中,可以像数组一样访问,索引returns是index
位置的char:
if(str[i - 1] - str[i] === 1)
// is the same as
if ((str.charAt(i - 1) - str.charAt(i)) === 1)
一旦检索到每个字符,代码就会执行隐式的“字符到数字”转换,这要归功于 -
运算符,但如果它是 +
相反,它会将两个字符连接成字符串(所以,要小心)。
明确总是更好,但如果您知道 -
的工作原理,它就可以完成这项任务。
循环从 1
开始,它检查 i - 1
处的字符,即第一次迭代中索引 0
处的字符,减去当前字符,是1
,表示当前字符 比前一个字符少 。
在这种情况下,计数器会求和。
Andrea 和 Mitya 已经搞定了。
下一步可能是切换到 first class based approach like using a specific Array
method such as reduce
。
这种方法如果实施得当,通常会改进 readability/maintainability 代码并实现更好的代码重用。
对于 OP 提供的示例,可以编写两个函数,即获取计数的实际方法和上面提到的第一个 class reducer 功能。由于 reduce
是处理数组的标准方式,因此 reducer/callback 的参数优先级也已明确指定 ...
[/* ... */].reduce(function(accumulator, currentValue, currentIndex, currentlyProcessedArray) {
// implement reducer/aggregation/accumulator logic here.
// the return value serves as the
// new `accumulator` value within
// the next iteration step.
// thus, always return something! ... e.g ...
return (accumulator + currentValue);
});
function aggregatePrecursorAndDecrementedSuccessorCount(count, char, idx, arr) {
const precursorValue = Number(arr[idx - 1]);
const incrementedCurrentValue = (Number(char) + 1);
const isValidCount = (precursorValue === incrementedCurrentValue);
return (count + (isValidCount ? 1 : 0));
//return (count + Number(isValidCount)); // cast boolean value to either 1 or 0.
}
function getPrecursorAndDecrementedSuccessorCount(int) {
return String(int) // - assure/typecast always a/into string value.
.split('') // - split string value into an array of single characters.
.reduce(aggregatePrecursorAndDecrementedSuccessorCount, 0);
}
console.log(getPrecursorAndDecrementedSuccessorCount(9876541110));
.as-console-wrapper { min-height: 100%!important; top: 0; }