尝试使用 reduce 查找偶数和奇数计数
Trying to find even and odd number count using reduce
我正在尝试使用 reduce 解决以下问题,但我无法获得对象中偶数和奇数的正确计数。
有人可以指导我我的代码有什么问题吗?
Create a function countBy
that accepts an array and a callback, and
returns an object. countBy
will iterate through the array and perform
the callback on each element. Each return value from the callback will
be saved as a key on the object. The value associated with each key
will be the number of times that particular return value was returned
function countBy(arr, fn) {
return arr.reduce(function(acc, nums) {
// console.log(nums);
let oddCount = 0
let evenCount = 0
console.log(nums, fn(nums))
if(fn(nums) === "even"){
evenCount++;
acc['even'] = evenCount;
} else {
oddCount++;
acc['odd'] = oddCount;
}
return acc
}, {}, 0)
}
function evenOdd(n) {
if (n % 2 === 0) return "even";
else return "odd";
}
var nums = [1, 2, 3, 4, 5];
console.log(countBy(nums, evenOdd)); // should log: { odd: 3, even: 2 }
您正在将 oddCount
和 evenCount
初始化为 0
在 reduce
回调的 中,因此在每次迭代中, 你的
evenCount++;
acc['even'] = evenCount;
只会将 evenCount
或 oddCount
递增到 1
。相反,在 回调之外初始化计数,以便对它们的更改在 reduce
回调的多次调用中保持不变:
function countBy(arr, fn) {
let oddCount = 0
let evenCount = 0
return arr.reduce(function(acc, nums) {
// console.log(nums);
console.log(nums, fn(nums))
if (fn(nums) === "even") {
evenCount++;
acc['even'] = evenCount;
} else {
oddCount++;
acc['odd'] = oddCount;
}
return acc
}, {}, 0)
}
function evenOdd(n) {
if (n % 2 === 0) return "even";
else return "odd";
}
var nums = [1, 2, 3, 4, 5];
console.log(countBy(nums, evenOdd)); // should log: { odd: 3, even: 2 }
或者,您可以通过检查累加器上已有的 属性 的值来完全避免外部变量:
const countBy = (arr, fn) => arr.reduce((acc, num) => {
const prop = fn(num);
acc[prop] = (acc[prop] || 0) + 1;
return acc;
}, {});
function evenOdd(n) {
if (n % 2 === 0) return "even";
else return "odd";
}
var nums = [1, 2, 3, 4, 5];
console.log(countBy(nums, evenOdd)); // should log: { odd: 3, even: 2 }
正如 CertainPerformance 所说,您正在重新初始化用于计数的变量。此外,您正在发送一个额外的参数来减少,不应该在那里。 Reduce 只需要 2 个参数。
这就是我的处理方式
function countBy(arr, fn) {
return arr.reduce(function(acc, nums) {
console.log(nums, fn(nums))
if(fn(nums) === "even"){
acc.even ++;
} else {
acc.odd ++;
}
return acc
}, {odd: 0, even: 0})
}
这个就是按照你想要的方式解决,根据log。如果您按照命令进行操作,我认为它实际上看起来像这样:
function countBy(arr, fn) {
return arr.reduce(function(acc, val) {
let key = fn(val);
if (!acc[key]) {
acc[key] = 1;
} else {
acc[key]++;
}
return acc;
}, {})
}
您最初的尝试依赖于返回 'odd' 或 'even' 的回调函数。上面的代码可以与返回任何值的函数一起使用
除了 Array.reduce
之外,您还可以通过 Array.forEach
和辅助函数以稍微不同的方式解决此问题:
const isEvenOrOdd = n => n % 2 ? "even" : "odd"
const propCount = (prop, obj) => obj[prop] = (obj[prop] || 0) + 1
const countBy = (arr, fn, obj={}) => {
arr.forEach(x => propCount(isEvenOrOdd(x), obj))
return obj
}
console.log(countBy([1, 2, 3, 4, 5], isEvenOrOdd));
我将从一个通用函数开始,用于在对象 o
上递增键 k
const incr = k => ({ [k]: val = 0, ...o }) =>
({ ...o, [k]: val + 1 })
const incrFoo =
incr ("foo")
console .log
( incrFoo ({})
// { foo: 1 }
, incrFoo ({ bar: 100 })
// { bar: 100, foo: 1 }
, incrFoo ({ foo: 3, bar: 100 })
// { bar: 100, foo: 4 }
, incr ("even") ({ odd: 2, even: 2 })
// { odd: 2, even: 3 }
)
插到reduce
上,countBy
基本就是自己写-
const incr = k => ({ [k]: val = 0, ...o }) =>
({ ...o, [k]: val + 1 })
const countBy = (f, xs = []) =>
xs .reduce
( (acc, x) => incr (f (x)) (acc)
, {}
)
console .log
( countBy
( x => x & 1 ? "odd" : "even"
, [ 1, 2, 3, 4, 5 ]
)
// { even: 2, odd: 3 }
, countBy
( x => x
, [ 'a', 'b', 'b', 'c', 'c', 'c' ]
)
// { a: 1, b: 2, c: 3 }
)
高阶函数不限于 map
、filter
和 reduce
- 使用延续组合器,下面的 $
,我们显示 countBy
作为递归函数。作为一个额外的优势,这个实现接受任何 iterable 作为输入;不仅是数组。
const incr = k => ({ [k]: val = 0, ...o }) =>
({ ...o, [k]: val + 1 })
const $ = x => k =>
k (x)
const None =
Symbol ()
const countBy = (f, [ x = None, ...xs ]) =>
x === None
? {}
: $ (f (x))
(key => $ (countBy (f, xs)) (incr (key)))
console .log
( countBy
( x => x & 1 ? "odd" : "even"
, [ 1, 2, 3, 4, 5 ]
)
// { even: 2, odd: 3 }
, countBy
( x => x
, "mississippi"
)
// { p: 2, s: 4, i: 4, m: 1 }
)
最简单的方法是创建一个函数来检查偶数,例如
const isEven = n => n%2 === 0;
初始化对象结果应该是这样的
{odd: 0, even: 0}
var nums = [1, 2, 3, 4, 5];
const isEven = n => n%2 == 0;
const result = nums.reduce((acc, curr) => {
if(isEven(curr)) acc.even++;
else acc.odd++;
return acc;
}, {odd: 0, even: 0})
console.log(result); // should log: { odd: 3, even: 2 }
我正在尝试使用 reduce 解决以下问题,但我无法获得对象中偶数和奇数的正确计数。
有人可以指导我我的代码有什么问题吗?
Create a function
countBy
that accepts an array and a callback, and returns an object.countBy
will iterate through the array and perform the callback on each element. Each return value from the callback will be saved as a key on the object. The value associated with each key will be the number of times that particular return value was returned
function countBy(arr, fn) {
return arr.reduce(function(acc, nums) {
// console.log(nums);
let oddCount = 0
let evenCount = 0
console.log(nums, fn(nums))
if(fn(nums) === "even"){
evenCount++;
acc['even'] = evenCount;
} else {
oddCount++;
acc['odd'] = oddCount;
}
return acc
}, {}, 0)
}
function evenOdd(n) {
if (n % 2 === 0) return "even";
else return "odd";
}
var nums = [1, 2, 3, 4, 5];
console.log(countBy(nums, evenOdd)); // should log: { odd: 3, even: 2 }
您正在将 oddCount
和 evenCount
初始化为 0
在 reduce
回调的 中,因此在每次迭代中, 你的
evenCount++;
acc['even'] = evenCount;
只会将 evenCount
或 oddCount
递增到 1
。相反,在 回调之外初始化计数,以便对它们的更改在 reduce
回调的多次调用中保持不变:
function countBy(arr, fn) {
let oddCount = 0
let evenCount = 0
return arr.reduce(function(acc, nums) {
// console.log(nums);
console.log(nums, fn(nums))
if (fn(nums) === "even") {
evenCount++;
acc['even'] = evenCount;
} else {
oddCount++;
acc['odd'] = oddCount;
}
return acc
}, {}, 0)
}
function evenOdd(n) {
if (n % 2 === 0) return "even";
else return "odd";
}
var nums = [1, 2, 3, 4, 5];
console.log(countBy(nums, evenOdd)); // should log: { odd: 3, even: 2 }
或者,您可以通过检查累加器上已有的 属性 的值来完全避免外部变量:
const countBy = (arr, fn) => arr.reduce((acc, num) => {
const prop = fn(num);
acc[prop] = (acc[prop] || 0) + 1;
return acc;
}, {});
function evenOdd(n) {
if (n % 2 === 0) return "even";
else return "odd";
}
var nums = [1, 2, 3, 4, 5];
console.log(countBy(nums, evenOdd)); // should log: { odd: 3, even: 2 }
正如 CertainPerformance 所说,您正在重新初始化用于计数的变量。此外,您正在发送一个额外的参数来减少,不应该在那里。 Reduce 只需要 2 个参数。
这就是我的处理方式
function countBy(arr, fn) {
return arr.reduce(function(acc, nums) {
console.log(nums, fn(nums))
if(fn(nums) === "even"){
acc.even ++;
} else {
acc.odd ++;
}
return acc
}, {odd: 0, even: 0})
}
这个就是按照你想要的方式解决,根据log。如果您按照命令进行操作,我认为它实际上看起来像这样:
function countBy(arr, fn) {
return arr.reduce(function(acc, val) {
let key = fn(val);
if (!acc[key]) {
acc[key] = 1;
} else {
acc[key]++;
}
return acc;
}, {})
}
您最初的尝试依赖于返回 'odd' 或 'even' 的回调函数。上面的代码可以与返回任何值的函数一起使用
除了 Array.reduce
之外,您还可以通过 Array.forEach
和辅助函数以稍微不同的方式解决此问题:
const isEvenOrOdd = n => n % 2 ? "even" : "odd"
const propCount = (prop, obj) => obj[prop] = (obj[prop] || 0) + 1
const countBy = (arr, fn, obj={}) => {
arr.forEach(x => propCount(isEvenOrOdd(x), obj))
return obj
}
console.log(countBy([1, 2, 3, 4, 5], isEvenOrOdd));
我将从一个通用函数开始,用于在对象 o
k
const incr = k => ({ [k]: val = 0, ...o }) =>
({ ...o, [k]: val + 1 })
const incrFoo =
incr ("foo")
console .log
( incrFoo ({})
// { foo: 1 }
, incrFoo ({ bar: 100 })
// { bar: 100, foo: 1 }
, incrFoo ({ foo: 3, bar: 100 })
// { bar: 100, foo: 4 }
, incr ("even") ({ odd: 2, even: 2 })
// { odd: 2, even: 3 }
)
插到reduce
上,countBy
基本就是自己写-
const incr = k => ({ [k]: val = 0, ...o }) =>
({ ...o, [k]: val + 1 })
const countBy = (f, xs = []) =>
xs .reduce
( (acc, x) => incr (f (x)) (acc)
, {}
)
console .log
( countBy
( x => x & 1 ? "odd" : "even"
, [ 1, 2, 3, 4, 5 ]
)
// { even: 2, odd: 3 }
, countBy
( x => x
, [ 'a', 'b', 'b', 'c', 'c', 'c' ]
)
// { a: 1, b: 2, c: 3 }
)
高阶函数不限于 map
、filter
和 reduce
- 使用延续组合器,下面的 $
,我们显示 countBy
作为递归函数。作为一个额外的优势,这个实现接受任何 iterable 作为输入;不仅是数组。
const incr = k => ({ [k]: val = 0, ...o }) =>
({ ...o, [k]: val + 1 })
const $ = x => k =>
k (x)
const None =
Symbol ()
const countBy = (f, [ x = None, ...xs ]) =>
x === None
? {}
: $ (f (x))
(key => $ (countBy (f, xs)) (incr (key)))
console .log
( countBy
( x => x & 1 ? "odd" : "even"
, [ 1, 2, 3, 4, 5 ]
)
// { even: 2, odd: 3 }
, countBy
( x => x
, "mississippi"
)
// { p: 2, s: 4, i: 4, m: 1 }
)
最简单的方法是创建一个函数来检查偶数,例如
const isEven = n => n%2 === 0;
初始化对象结果应该是这样的
{odd: 0, even: 0}
var nums = [1, 2, 3, 4, 5];
const isEven = n => n%2 == 0;
const result = nums.reduce((acc, curr) => {
if(isEven(curr)) acc.even++;
else acc.odd++;
return acc;
}, {odd: 0, even: 0})
console.log(result); // should log: { odd: 3, even: 2 }