【问题标题】:js - How to change one key's value based on another key's value in array of objectsjs - 如何根据对象数组中另一个键的值更改一个键的值
【发布时间】:2012-07-04 20:38:46
【问题描述】:

我有一个这样的对象数组:

var chartData = [{count: 0, idTag: "24"}
                 {count: 0, idTag: "25"}
                 {count: 0, idTag: "26"}]

我的代码做了一些工作并生成了一个数字 (totalValue)。如果totalValueidTag 匹配,则其count 增加一:

for (i=0; i<timesFlipped; i++) {
    totalValue = runTrial();
    for (j=0; j<chartData.length; j++) {
        if (chartData[j].idTag === totalValue) {
            chartData[j].count += 1;
            break;
        }
    }
}

这是一个简单的例子,但chartData 可以容纳几十个对象,而timesFlipped 可以是数十万次迭代。

这是基于匹配idTag 值更改count 值的最佳方式吗?有没有办法只用正确的idTag 值找到数组的索引,而无需遍历整个对象数组?

如果您需要更多上下文,这是我正在处理的页面:http://blue.butler.edu/~aazman/coupling/


更新:

感谢所有建议。我有点根据我所看到的形成了自己的解决方案。关于这个项目的更多背景信息,这让我找到了我的解决方案:

  • chartData 的长度和最小 idTag 值是根据用户点击提交时的输入计算得出的
  • 一旦计算出minlength(因此最大idTag 已知),chartData 就会被迭代初始化:

var min = 23-5*numNickel-numPenny; //numNickel &amp; numPenny are the user inputs

var length = 5*(2*numNickel+1)+2*numPenny;

var tempTag = min;

for (j=0;j&lt;length;j++) {

chartData[j] = {count: 0, idTag = tempTag};

tempTag++;

}

  • 由于特定于游戏规则的原因,idTag 值(无论有多少)对称地以idTag:25 为中心(例如 idTags = {24, 25, 26} 或 idTags = {20,21,22, 23,24,25,26,27,28,29,30}。无论chartData的长度如何,长度始终是奇数,idTag:25始终是[(chartData.length-1)/2]的第索引。

因此,如果 chartData 的 idTag 是 {20,21,22,23,24,25,26,27,28,29,30} 并且如果 runTrial() 给出 totalValue = 22,那么 idTag:22 将始终位于索引 (totalValue - min)

所以我改变了chartData的初始化和计数增加的方式:

for (j=0; j<length; j++) {
    chartData[j] = {count: 0};  //based on what I'm doing with chartData next, I need each index to still be an object
}

for (i=0; i<timesFlipped; i++) {
    totalValue = runTrial();
    var index = totalValue - min;
    chartData[index].count++;
}

感谢大家的帮助:)

【问题讨论】:

  • 该数组是否按idTag排序?
  • 你可以随意改变chartData的结构吗?
  • @zerkms 是的,数组按 idTag 排序。该数组是按顺序创建的,因此按定义进行排序。
  • @Danrumb 是的,我可以改变chartData的结构

标签: javascript arrays iteration


【解决方案1】:

我建议使用客户端数据库存储机制,让查询为您计算。

这使它更易于监督并减少了来自各种病毒扫描程序的警告,而且您无需每次都重新获取数据。

另一种方法是使用服务器端数据库并通过 json 检索您想要的值。

另一种防止浏览器冻结的方法是让您的循环在 webworker 中运行,这样它就成为一个线程并且不会锁定浏览器。

【讨论】:

    【解决方案2】:

    您可以创建另一个指向 chartData 数组中的对象的对象,如下所示:

    var idToChart = {};
    for (var i = 0; i < chartData.length; i++) {
        var currChart = chartData[i];
        idToChart[currChart.idTag] = currChart;
    }
    

    然后使用

    var chart = idToChart[totalValue];
    chart.count++;
    

    访问对象的属性应该比每次循环遍历数组要快。

    如果正如@zerkms 指出的那样,您的数组按idtag 排序,您甚至不需要创建另一个对象并且可以直接访问该数组。理想情况下,chartData 将以 idToChart 或排序数组格式开始。

    【讨论】:

      【解决方案3】:

      我宁愿维护一个以“idTag”值作为键并将其计数作为值的中间散列,使用 for 循环执行操作,然后在 for 循环完成后从中间散列生成 charData。

      【讨论】:

        【解决方案4】:

        如果您可以随意更改 chartData 的结构,为什么不将其设为哈希而不是数组?

        var chartData = {24: 0,
                         25: 0,
                         26: 0};
        

        然后循环就变成了

        for (i=0; i<timesFlipped; i++) {
            chartData[runTrial()]++;        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-09-17
          • 2017-08-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-31
          • 2021-09-30
          相关资源
          最近更新 更多