【问题标题】:How to modify a multidimensional array with keys/values in Javascript more efficiently?如何更有效地使用 Javascript 中的键/值修改多维数组?
【发布时间】:2021-05-28 02:41:11
【问题描述】:

我会直奔主题的。

我想更改以下数组中特定 ID 和 dataID 的半径值:

var data = [{
  ID: 0,
  type: 'circle',
  Name: 'Tom',
  MoreData: [{
    dataID: 123,
    dimData: {
      radius: 25,
      var: 15
    }
  }, {
    dataID: 345,
    dimData: {
      radius: 35,
      var: 65
    }
  }]
}, {
  ID: 1,
  type: 'circle',
  Name: 'Mat',
  MoreData: [{
    dataID: 678,
    dimData: {
      radius: 40,
      var: 30
    }
  }, {
    dataID: 91011,
    dimData: {
      radius: 50,
      var: 50
    }
  }]
}];

我目前的解决方案:

    var data = [{
      ID: 0,
      type: 'circle',
      Name: 'Tom',
      MoreData: [{
        dataID: 123,
        dimData: {
          radius: 25,
          var: 15
        }
      }, {
        dataID: 345,
        dimData: {
          radius: 35,
          var: 65
        }
      }]
    }, {
      ID: 1,
      type: 'circle',
      Name: 'Mat',
      MoreData: [{
        dataID: 678,
        dimData: {
          radius: 40,
          var: 30
        }
      }, {
        dataID: 91011,
        dimData: {
          radius: 50,
          var: 50
        }
      }]
    }];
    

    var doSomething = function(array, IDVal, dataIDVal, RadiusVal) {
    
      //Search array for ID and then dataID and then set the value of that dataID's Radius to RadiusVal
      for (var i = 0; i < array.length; i++) {
        if (array[i].ID == IDVal) {
          for (var j = 0; j < array[i].MoreData.length; j++) {
            if (array[i].MoreData[j].dataID == dataIDVal) {
                console.log('Radius Before: ' +  array[i].MoreData[j].dimData.radius);
              array[i].MoreData[j].dimData.radius = 20000;
              console.log('Radius After: ' +  array[i].MoreData[j].dimData.radius);
            }
    
          }
    
        }
    
      }
    
    }
    doSomething(data, 0, 345, 100);
    console.log(data[0]);

我想先搜索正确的ID,然后获取正确的dataID来改变dimData.Radius。

有没有更有效的方法来做到这一点?不用说,数据数组可能非常大,而且 MoreData 数组还包含更多值(dimData 也是如此)。我想知道是否有更快的方法来实现上述结果。

编辑:要回答几个问题,唯一可以保证的是 ID 值始终是结构化的,因此它每次都会递增 1,但我不相信数据会以其他方式排序.但是,如果数据集也已排序,我将不胜感激。

编辑 2: 尝试了一个使用 .filter 的解决方案,但结果是几个函数相互嵌套,看起来很混乱。

如果有人想要该解决方案,请点击此处:How do I pass an extra parameter to the callback function in Javascript .filter() method?

如果代码片段不起作用,请在 JS Fiddle 上链接(我是新手): https://jsfiddle.net/53pa2xst/

【问题讨论】:

  • Javascript 与 Java 无关。
  • 数据是否完全排序?

标签: javascript arrays performance multidimensional-array key-value


【解决方案1】:

使用嵌套循环在时间复杂度 O(n^2) 方面非常昂贵 更好的方法是像这样将其简化为 O(n)

var data = [{
    ID: 0,
    type: 'circle',
    Name: 'Tom',
    MoreData: [{
        dataID: 123,
        dimData: {
            radius: 25,
            var: 15
        }
    }, {
        dataID: 345,
        dimData: {
            radius: 35,
            var: 65
        }
    }]
}, {
    ID: 1,
    type: 'circle',
    Name: 'Mat',
    MoreData: [{
        dataID: 678,
        dimData: {
            radius: 40,
            var: 30
        }
    }, {
        dataID: 91011,
        dimData: {
            radius: 50,
            var: 50
        }
    }]
}];


var doSomething = function (array, IDVal, dataIDVal, RadiusVal) {
    let list = {};

    array.map((ar, pos) => {
        list[ar.ID] = pos;
    })

    console.log("before : ", array[0].MoreData)
    array[list[IDVal]].MoreData
    .filter(a => a.dataID == dataIDVal)[0].dimData.radius = 20000;
    console.log("After : ", array[0].MoreData)
}
doSomething(data, 0, 345, 100);

您可能会考虑添加一些验证器来检查 Id 是否存在。

【讨论】:

    【解决方案2】:

    我不确定您的数组必须达到什么大小才能让您在过滤数组时注意到速度变慢,因此您实际上可能不需要其他结构。

    据我所知,Array.prototype.filter 将是 O(n)。如果您对 data 所做的一切都是查找值,那么将其转换为哈希映射/对象会更高效——更符合 O(1) 的要求。

    例如

    var data = {
      0: {
        type: 'circle',
        Name: 'Tom',
        MoreData: {
          123: {
            dimData: {
              radius: 25,
              var: 15
            }
          }, {
          345: {
            dimData: {
              radius: 35,
              var: 65
            }
          }
        }      
      }
    

    在您的搜索功能中,您可以访问类似的结构

    let shape = data[IdVal]
    let moreData = shape[dataIdVal]
    let radius = moreData['radius']
    

    您是否只使用这种结构完全取决于您的访问模式。如果您仍然只是根据它们的 ID 选择我们的某些元素,那么这将是一个更有效的选择。但是,如果您在整个结构中进行过滤/搜索或进行任何聚合工作,那么使用基于数组的结构和过滤可能会更好。 (如果您有兴趣查找“平衡二叉树”或“treps”作为另一种可能的解决方案)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-02
      • 2020-03-27
      • 1970-01-01
      • 2017-06-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      相关资源
      最近更新 更多