【问题标题】:JavaScript: Create a function groupBy that accepts an array and a callback, and returns an objectJavaScript:创建一个接受数组和回调并返回对象的函数 groupBy
【发布时间】:2019-06-10 23:12:52
【问题描述】:

我的目标如下:

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

【问题讨论】:

  • 因为数组排序,函数执行时,会搜索obj中是否有“1”而没有,所以打印undefined,然后搜索“2”,即@ 987654325@ 然后将其添加到obj 后,它会打印 2.1,因为 "2" (key) 中有值,即 [2.1] 因为函数推送到 "2" (key) 2.1 (array) 然后它变为 [2.1] 并且不应打印最后一个 undefined 但我认为它来自浏览器控制台

标签: javascript function object if-statement keyvaluepair


【解决方案1】:

因为它显示了该项目是否存在。如果没有,则转到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; }

【讨论】:

    【解决方案2】:

    当你这样做时

    console.log(obj[key])
    

    你不知道对象是否有说键;毕竟,只有 之后,您才将数组分配给该键,如果没有关联的值:

    if(obj[key] === undefined){
      obj[key] = [];
    }
    

    所以,在每次迭代中,如果被迭代的键还没有被放到对象上,它会记录undefined,然后在同一次迭代中,一个空数组将被分配给对象上的那个键.

    例如,在第一次迭代中,i1.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] }

    【讨论】:

      猜你喜欢
      • 2021-01-13
      • 1970-01-01
      • 2014-04-29
      • 1970-01-01
      • 2015-02-10
      • 2021-11-29
      • 2023-03-15
      • 2019-10-27
      • 1970-01-01
      相关资源
      最近更新 更多