【问题标题】:for-loop causes Cannot set property '0' of undefinedfor-loop 导致无法设置未定义的属性“0”
【发布时间】:2021-07-11 08:17:43
【问题描述】:

在下面发布的代码中,我想循环遍历数组的内容

features[0]["values_"]["geometry"]["flatCoordinates"]

对于所有在 for 循环之外的控制台语句,它们会被打印出来并包含数据。但是,当我运行应用程序时,我会收到以下错误

ERROR TypeError: Cannot set property '0' of undefined

为了解决这个问题,我注释掉了 for 循环中的前两行,并打印了变量“i”的值。只有当我 arivate 循环内的前两行时,才会收到错误消息。 请告诉我如何解决此错误

代码

private renderSelectedSite(){
    var features = (new GeoJSON()).readFeatures(this.selectedSite.geometry);
    console.log("this.selectedSite.geometry: ",this.selectedSite.geometry)
    console.log("features ",features)
    console.log("features ",features[0]["values_"]["geometry"]["flatCoordinates"])
    console.log("features ",features[0]["values_"]["geometry"]["flatCoordinates"].length)//84
    console.log("features ",features[0]["values_"]["geometry"]["flatCoordinates"][0])//736437.816446109
    var points: any[];
    for (var i = 0; i < features[0]["values_"]["geometry"]["flatCoordinates"].length; i++) {
        var e = features[0]["values_"]["geometry"]["flatCoordinates"][i];
        points[i] = transform(e,'EPSG:4326','EPSG:3857');
        console.log("points[i] ",i)
    }

【问题讨论】:

  • 您能否将问题中的代码调整为可以工作的 sn-p,我们可以在我们的答案中使用和修改它?
  • 添加您正在尝试的坐标通常非常有用(正如您在本网站中看到的,坐标顺序在某些基准上发生变化,有些使用角度,有些使用米(或其他长度单位)等)

标签: javascript angular typescript openlayers geojson


【解决方案1】:

你需要初始化变量points

var points: any[] = [];

以下是我建议的一些 QOL 改进:

  1. 使用const/let 而不是var。有关规范差异,请参阅 here
  2. 使用Array#map 而不是for
private renderSelectedSite(){
  const features = (new GeoJSON()).readFeatures(this.selectedSite.geometry);
  let points: any[] = features[0]["values_"]["geometry"]["flatCoordinates"].map(e => 
    transform(e,'EPSG:4326','EPSG:3857')
  );
}
  1. 正如@Cerbrus 在评论中提到的那样,我还将帮助进行类型检查以定义对象的类型(例如,使用 TS 接口)并使用点访问而不是使用括号表示法来访问属性。李>

更新:登录Array#map

将回调括在大括号中,如果您有多个语句,则显式返回响应。

let points: any[] = features[0]["values_"]["geometry"]["flatCoordinates"].map(e => {
  console.log(transform(e,'EPSG:4326','EPSG:3857'));
  return transform(e,'EPSG:4326','EPSG:3857');
});

console.log(points);

更新:重复问题

希望这也解决了herehere 的问题。请停止针对同一问题发布重复的问题。


如果您确定平面坐标始终只包含 8 个条目,您可以轻松构建排列好的坐标。

const flatCoords = features[0]["values_"]["geometry"]["flatCoordinates"];
const coords = [
  [flatCoords[0], flatCoords[1]],
  [flatCoords[2], flatCoords[3]],
  [flatCoords[4], flatCoords[5]],
  [flatCoords[6], flatCoords[7]],
];

然后您可以迭代数组并使用Array#map 获取点。

let points = coords.map(coord => transform(coord,'EPSG:4326','EPSG:3857'));

更新:平面坐标的动态数量

您可以编写一个快速例程将平面坐标转换为所需的格式

toCoords(flatCoords: any) {
  let coords = [];
  for (let i = 0; i < flatCoords.length; i += 2) {
    coords.push([flatCoords[i], flatCoords[i+1]])
  }
  return coords;
}
const coords = this.toCoords(features[0]["values_"]["geometry"]["flatCoordinates"];
let points = coords.map(coord => transform(coord,'EPSG:4326','EPSG:3857'));

【讨论】:

  • 使用点访问而不是括号:features[0].values_.geometry.flatCoordinates
  • @Cerbrus:好点子,但是如果没有正确的类型来指导,TS linter 可能会抛出类似“找不到属性”的错误。我会把它添加到帖子中。
  • TS 将相同的规则应用于这两种访问类型。如果它在括号中工作,它将以点表示法工作。所以,features 在这里是强类型的并且 TS 知道哪些属性有效,或者它是 any
  • 你能告诉我为什么当我打印转换的内容时我收到 undefined 吗?console.log(transform(e,'EPSG:4326','EPSG:3857')) 返回 undefined
  • 您是否正在in.map 回调?或者你有没有把这条线断章取意?注意.map 有一个参数e...
猜你喜欢
  • 1970-01-01
  • 2014-06-02
  • 2019-07-14
  • 2021-11-27
  • 1970-01-01
  • 2019-04-10
  • 2022-10-30
  • 2023-02-10
相关资源
最近更新 更多