我的目标如下:
创建一个函数 groupBy ,它接受一个数组和一个回调,并返回一个对象。 groupBy 将迭代数组并对每个元素执行回调。回调的每个返回值都将保存为对象上的键。与每个键关联的值将是一个数组,其中包含传递到回调时产生该返回值的所有元素。
以下代码成功执行:
function groupBy(array, inputFunc) {
let obj = {};
for(let i of array){
let key = inputFunc(i);
// QUESTION on line of code below:
console.log(obj[key])
if(obj[key] === undefined){
obj[key] = [];
}
obj[key].push(i)
}
return obj;
}
// Uncomment these to check your work!
const decimals = [1.3, 2.1, 2.4];
const floored = function(num) { return Math.floor(num); };
console.log(groupBy(decimals, floored)); // should log: { 1: [1.3], 2: [2.1, 2.4] }
但是我对代码有点困惑。具体来说,当我这样做时:
console.log(obj[key])
上面的代码行似乎返回:
undefined
undefined
[ 2.1 ]
undefined
为什么打印未定义?那是从哪里来的?
因为我不明白 undefined 是从哪里来的,所以我不明白为什么需要 if 语句。
因为它显示该项目是否存在。如果没有,则转到
if
语句。将 console.log
放在 if
语句之后即可删除所有 undefined
。
function groupBy(array, inputFunc) {
let obj = {};
for (let i of array) {
let key = inputFunc(i);
if (obj[key] === undefined) {
obj[key] = [];
}
console.log(obj[key]);
obj[key].push(i);
}
return obj;
}
const decimals = [1.3, 2.1, 2.4];
const floored = function(num) {
return Math.floor(num);
};
console.log(groupBy(decimals, floored));
.as-console-wrapper { max-height: 100% !important; top: auto; }
请注意,它不是必需的 - 如果您想要的只是从函数返回的
obj
:
function groupBy(array, inputFunc) {
let obj = {};
for (let i of array) {
let key = inputFunc(i);
if (obj[key] === undefined) {
obj[key] = [];
}
obj[key].push(i);
}
return obj;
}
const decimals = [1.3, 2.1, 2.4];
const floored = function(num) {
return Math.floor(num);
};
console.log(groupBy(decimals, floored));
.as-console-wrapper { max-height: 100% !important; top: auto; }
当你这样做时
console.log(obj[key])
你不知道该物体是否已经说过钥匙;毕竟,如果没有关联值,则只有after才将数组分配给该键:
if(obj[key] === undefined){
obj[key] = [];
}
因此,在每次迭代中,如果正在迭代的键尚未放入对象上,它将记录
undefined
,并且稍后在同一次迭代中,将向对象上的该键分配一个空数组。
例如,在第一次迭代中,
i
是1.3
,因此生成的密钥是let key = inputFunc(i);
-> let key = inputFunc(1.3);
-> let key = 1
。但该对象一开始根本没有键,所以
obj[1]
计算为
undefined
,后面的 if
语句检测到这一点,并将一个数组分配给该键:
if(obj[key] === undefined){
obj[key] = [];
}
在第一次迭代中,解决为
if(obj[1] === undefined){
obj[1] = [];
}
// ->
if(undefined === undefined){
obj[1] = [];
}
您还可以考虑使用
reduce
来代替,它更实用,并且在将数组转换为奇异值时可以说更合适:
const groupBy = (array, inputFunc) => array.reduce((a, elm) => {
const key = inputFunc(elm);
if (!a[key]) {
a[key] = [];
}
a[key].push(elm);
return a;
}, {});
const decimals = [1.3, 2.1, 2.4];
const floored = function(num) { return Math.floor(num); };
console.log(groupBy(decimals, floored)); // should log: { 1: [1.3], 2: [2.1, 2.4] }
function groupBy(arr, CB) {
let fOut = {};
arr.forEach( (e) => {
if (!fOut[CB(e)]) fOut[CB(e)] = []; // if theres no key for the CB(e), create and set value as empty arr
fOut[CB(e)].push(e); // push the (raw) element to the key of CB(e)
});
return fOut;
}