【问题标题】:Get object filter to work without error in Google Apps Script让对象过滤器在 Google Apps 脚本中正常工作
【发布时间】:2020-10-27 02:18:04
【问题描述】:

我有以下过滤器可以在 jsfiddle(和 stackoverflow 代码段)中使用,但是当我在 google 应用程序脚本中逐字粘贴并运行它时它不起作用。我收到一条错误消息“TypeError:无法将未定义或 null 转换为对象(第 94 行)” - 第 94 行是 if (Object.keys(obj).includes(obj_key)) {。然后,如果我检查日志,它会记录正确的输出,但我仍然想知道为什么会出现这个讨厌的错误。

日志:

[20-10-26 22:13:29:611 EDT] fruits: strawberry
[20-10-26 22:13:29:613 EDT] vegetables: lettuce,radish
[20-10-26 22:13:29:614 EDT] pasta: spaghetti,rigatoni,lasagna,fettuccine
[20-10-26 22:13:29:633 EDT] TypeError: Cannot convert undefined or null to object
    at filtered(test:94:16)

另外,我希望输出采用“生菜,萝卜”的形式,它们之间有一个空格,但如果我将其设为.join(", "),它不会做任何事情。

var obj = {
  "c4ecb": {"id": [3]},
  "a4269": {"id": [34,36]},
  "d76fa": {"id": [54,55,60,61]},
  "58cb5": {"id": [67]}
}

var response = 
    [{
      "success": true,
      "data": [
        {
          "key": "c4ecb",
          "name": "fruits",
          "options": [
            {
              "label": "strawberry",
              "id": 3
            },
            {
              "label": "apple",
              "id": 4
            },
            {
              "label": "pineapple",
              "id": 5
            },
            {
              "label": "Other",
              "id": 31
            }
          ],
        }
      ]
    },
    {
      "success": true,
      "data": [
        {
          "key": "a4269",
          "name": "vegetables",
          "options": [
            {
              "label": "lettuce",
              "id": 34
            },
            {
              "label": "cucumber",
              "id": 35
            },
            {
              "label": "radish",
              "id": 36
            }
          ],
        }
      ]
    },
    {
      "success": true,
      "data": [
        {
          "key": "d76fa",
          "name": "pasta",
          "options": [
            {
              "label": "spaghetti",
              "id": 54
            },
            {
              "label": "rigatoni",
              "id": 55
            },
            {
              "label": "linguine",
              "id": 56
            },
            {
              "label": "lasagna",
              "id": 60
            },
            {
              "label": "fettuccine",
              "id": 61
            }
          ],
        }
      ]
    }];
 
 
 function filteredLabelsAsString(obj_key, obj, content=response) {
    // sanity check: obj must contain obj_key
    if (Object.keys(obj).includes(obj_key)) {
        return content.filter((item) => {
            // filter content using value of obj_key
            return item.data[0].key == obj_key;
        }).map((item) => {
            // item : { success: true, data: [] }
            // map over options array
            return item.data[0].options.map((opt) => {
                // option : {id, label}
                // return the label if the id is in the obj object's list
                if (obj[item.data[0].key].id.includes(opt.id))
                    return opt.label;
            }).filter((label) => {
                // filter out empty items
                return label !== undefined;
            });
        }).join(",");
    }
    // if obj does not contain obj_key return empty string
    return "";
}   
console.log("fruits: " + filteredLabelsAsString("c4ecb", obj));  
console.log("vegetables: " + filteredLabelsAsString("a4269", obj));
console.log("pasta: " + filteredLabelsAsString("d76fa", obj));

【问题讨论】:

  • 来自it won't work when I paste and run it verbatim in google apps script.,在您的情况下,我认为您可能已经直接运行了函数filteredLabelsAsString。在那种情况下,就会发生这样的错误。例如,当您要运行脚本时,将整个脚本放到function sample() {###}### 并运行函数sample() 怎么样?这样就可以在控制台看到结果值了。
  • 我确实直接运行了函数filteredLabelsAsString。当我注释掉函数体时,日志现在只显示[20-10-26 22:42:06:148 EDT] fruits: undefined [20-10-26 22:42:06:150 EDT] vegetables: undefined [20-10-26 22:42:06:152 EDT] pasta: undefined
  • 感谢您的回复。我认为您的问题的原因是直接运行函数filteredLabelsAsString。那么当你测试我的建议时,你得到了什么结果?或者,当你运行function sample() {console.log("fruits: " + filteredLabelsAsString("c4ecb", obj)); console.log("vegetables: " + filteredLabelsAsString("a4269", obj)); console.log("pasta: " + filteredLabelsAsString("d76fa", obj));}的函数并运行sample(),你会得到什么结果?
  • 我不确定我是否理解您对示例函数的要求。你想让我把filteredLabesAsString函数注释掉,然后运行下面的函数吗? function sample() {console.log("fruits: " + filteredLabelsAsString("c4ecb", obj)); console.log("vegetables: " + filteredLabelsAsString("a4269", obj)); console.log("pasta: " + filteredLabelsAsString("d76fa", obj));} ?
  • 感谢您的回复。我不得不为我糟糕的英语水平道歉。由于我糟糕的英语水平,我把你弄糊涂了。我对此深表歉意。为了通过 Google Apps 脚本运行您的脚本并检索结果值,我建议修改后的脚本作为答案。

标签: javascript arrays object google-apps-script


【解决方案1】:

修改点:

  • 当您将问题中的脚本放入脚本编辑器并运行filteredLabelsAsStringobj_keyobj 时为undefined。这样,就会出现TypeError: Cannot convert undefined or null to object 的错误。
    • 我认为这是您的问题的原因。
  • 为了使用 Google Apps 脚本检索结果值,需要将参数提供给函数 filteredLabelsAsString
    • 但是,在您的情况下,我认为response 不是全局变量可能是合适的。

当以上几点反映到你的脚本中时,它变成如下。

修改脚本:

请将以下脚本复制并粘贴到脚本编辑器并运行sample() 的功能。这样,您可以在日志中看到结果值。

function filteredLabelsAsString(obj_key, obj, content=response) { // or function filteredLabelsAsString(obj_key, obj, content) {
    // sanity check: obj must contain obj_key
    if (Object.keys(obj).includes(obj_key)) {
        return content.filter((item) => {
            // filter content using value of obj_key
            return item.data[0].key == obj_key;
        }).map((item) => {
            // item : { success: true, data: [] }
            // map over options array
            return item.data[0].options.map((opt) => {
                // option : {id, label}
                // return the label if the id is in the obj object's list
                if (obj[item.data[0].key].id.includes(opt.id))
                    return opt.label;
            }).filter((label) => {
                // filter out empty items
                return label !== undefined;
            });
        }).join(",");
    }
    // if obj does not contain obj_key return empty string
    return "";
}

// Please run this function.
function sample() {
  var obj = {
    "c4ecb": {"id": [3]},
    "a4269": {"id": [34,36]},
    "d76fa": {"id": [54,55,60,61]},
    "58cb5": {"id": [67]}
  }
  
  var response = 
      [{
        "success": true,
        "data": [
          {
            "key": "c4ecb",
            "name": "fruits",
            "options": [
              {
                "label": "strawberry",
                "id": 3
              },
              {
                "label": "apple",
                "id": 4
              },
              {
                "label": "pineapple",
                "id": 5
              },
              {
                "label": "Other",
                "id": 31
              }
            ],
          }
        ]
      },
      {
        "success": true,
        "data": [
          {
            "key": "a4269",
            "name": "vegetables",
            "options": [
              {
                "label": "lettuce",
                "id": 34
              },
              {
                "label": "cucumber",
                "id": 35
              },
              {
                "label": "radish",
                "id": 36
              }
            ],
          }
        ]
      },
      {
        "success": true,
        "data": [
          {
            "key": "d76fa",
            "name": "pasta",
            "options": [
              {
                "label": "spaghetti",
                "id": 54
              },
              {
                "label": "rigatoni",
                "id": 55
              },
              {
                "label": "linguine",
                "id": 56
              },
              {
                "label": "lasagna",
                "id": 60
              },
              {
                "label": "fettuccine",
                "id": 61
              }
            ],
          }
        ]
      }];
  console.log("fruits: " + filteredLabelsAsString("c4ecb", obj, response));  
  console.log("vegetables: " + filteredLabelsAsString("a4269", obj, response));
  console.log("pasta: " + filteredLabelsAsString("d76fa", obj, response));
}

结果:

当上面脚本的函数sample()运行时,可以在日志中看到以下值。

fruits: strawberry
vegetables: lettuce,radish
pasta: spaghetti,rigatoni,lasagna,fettuccine

注意:

objresponse作为全局变量时,也可以使用下面的脚本。

var obj = {
  "c4ecb": {"id": [3]},
  "a4269": {"id": [34,36]},
  "d76fa": {"id": [54,55,60,61]},
  "58cb5": {"id": [67]}
}

var response = 
    [{
      "success": true,
      "data": [
        {
          "key": "c4ecb",
          "name": "fruits",
          "options": [
            {
              "label": "strawberry",
              "id": 3
            },
            {
              "label": "apple",
              "id": 4
            },
            {
              "label": "pineapple",
              "id": 5
            },
            {
              "label": "Other",
              "id": 31
            }
          ],
        }
      ]
    },
    {
      "success": true,
      "data": [
        {
          "key": "a4269",
          "name": "vegetables",
          "options": [
            {
              "label": "lettuce",
              "id": 34
            },
            {
              "label": "cucumber",
              "id": 35
            },
            {
              "label": "radish",
              "id": 36
            }
          ],
        }
      ]
    },
    {
      "success": true,
      "data": [
        {
          "key": "d76fa",
          "name": "pasta",
          "options": [
            {
              "label": "spaghetti",
              "id": 54
            },
            {
              "label": "rigatoni",
              "id": 55
            },
            {
              "label": "linguine",
              "id": 56
            },
            {
              "label": "lasagna",
              "id": 60
            },
            {
              "label": "fettuccine",
              "id": 61
            }
          ],
        }
      ]
    }];
 
 
 function filteredLabelsAsString(obj_key, obj, content=response) {
    // sanity check: obj must contain obj_key
    if (Object.keys(obj).includes(obj_key)) {
        return content.filter((item) => {
            // filter content using value of obj_key
            return item.data[0].key == obj_key;
        }).map((item) => {
            // item : { success: true, data: [] }
            // map over options array
            return item.data[0].options.map((opt) => {
                // option : {id, label}
                // return the label if the id is in the obj object's list
                if (obj[item.data[0].key].id.includes(opt.id))
                    return opt.label;
            }).filter((label) => {
                // filter out empty items
                return label !== undefined;
            });
        }).join(",");
    }
    // if obj does not contain obj_key return empty string
    return "";
}

function sample() {
  console.log("fruits: " + filteredLabelsAsString("c4ecb", obj));  
  console.log("vegetables: " + filteredLabelsAsString("a4269", obj));
  console.log("pasta: " + filteredLabelsAsString("d76fa", obj));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2017-04-07
    • 2017-11-06
    • 1970-01-01
    相关资源
    最近更新 更多