JavaScript:创建一个函数 groupBy 接受数组和回调,并返回一个对象

问题描述 投票:0回答:3

我的目标如下:

创建一个函数 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 语句。

javascript function object if-statement keyvaluepair
3个回答
0
投票

因为它显示该项目是否存在。如果没有,则转到

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; }


0
投票

当你这样做时

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] }


0
投票

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;
}

© www.soinside.com 2019 - 2024. All rights reserved.