【问题标题】:Loop through array of objects and return accumulated data from those objects循环遍历对象数组并从这些对象返回累积的数据
【发布时间】:2018-07-26 07:55:00
【问题描述】:

所以我有一个来自我的数据库的数组。数组内部有一个对象。我有工作时间和员工 ID 以及网页上的员工列表。当我单击员工时,我想查看分配给该员工的小时数。

var makeup_hrs = api_resp.makeup_data[key];

for (var i = 0; i < makeup_hrs.length; i++) {
  var obj = makeup_hrs[i];
  console.log(obj);
  for (var o in obj) {
    var y = obj[o];
    console.log("make up hours ", y, "id: ", emp_id)

    var x = document.getElementById("makeUpHours").innerHTML = y;
    console.log(x);

    // $('#makeUpHours').html(y);
  }
}

任何时候我打印 make up hours 和 emp_id - 它给了我那个员工的数量和他的小时价值。但是当我使用 innerHTML 时,它只显示最后几个小时的值,而不是特定员工的特定小时。

这样(控制台输出)我的数据库中目前只有 2 名员工:

 make up hours  4 id:  2891
make up hours  7 id:  1978

这是我的 html(它在模态 - 引导程序内部)

<div class="form-group">   <label class="col-sm-3"> Hours </label> 
  &nbsp;<span id="makeUpHours"></span></div>

当我点击图标时 - 模态弹出。每个图标都分配给一个员工 ID

员工 id 来自一个数组,而小时数来自另一个数组。不知何故,当我将 2 个值一起控制台时,它们会将正确的 ID 号分配给正确的小时数。

【问题讨论】:

  • 你能提供一个你正在使用的数据的模拟吗?
  • 您能否提供一个精简版的 HTML。你说它只显示最后几个小时,这是有道理的,因为你的 for 循环将 y 值保存在同一个 HTML 元素中(#makeUpHours)。
  • 向我们提供格式正确的数据样本
  • 听起来像是 Array.reduce() 的工作。但我们确实需要知道源数据的结构。
  • @Shilly 不是,问题在于 OP 只是为循环的每个索引覆盖相同 DOM 元素中的数据

标签: javascript arrays loops


【解决方案1】:

您在每次迭代中设置innerHTML,而不是添加到其中(因此只会显示最后一次迭代)。

这是一个示例解决方案:

// sample data
const employees = [{
  name: 'Bob',
  hours: 10
}, {
  name: 'Jane',
  hours: 15
}, {
  name: 'John',
  hours: 20
}]

const ul = document.getElementById('employees')

// how you want to represent an employee's info
const stringifyData = employee => `${employee.name}: ${employee.hours} hours`

// add employee HTML 
const addEmployee = str => {
  ul.innerHTML += `<li>${str}</li>`
}

// iterate
employees.map(stringifyData).forEach(addEmployee)
&lt;ul id="employees"&gt;&lt;/ul&gt;

我更喜欢将数据转换与 DOM 操作分开(更容易测试),但您当然可以在一次迭代中同时完成。

【讨论】:

    【解决方案2】:

    让我们做一些理论知识来更好地理解问题,因为理解潜在问题是找到解决方案的关键。

    假设你有一个对象数组:

    [{
      id: 1,
      x: 10,
    }, {
      id: 2,
      x: 20,
    }, {
      id: 3,
      x: 30,
    }];
    

    因此,您希望将此 HTML 标记放入任意 DOM 元素的 innerHTML 属性中:

    <p>id: 1, x: 10</p>
    <p>id: 2, x: 20</p>
    <p>id: 3, x: 30</p>
    

    (注意缺少一个共同的父级,这对 innerHTML 有效)

    您可以使用for 循环遍历一个对象数组,然后像您一样使用另一个for 循环遍历每个对象的属性,只需要说明您需要累积结果 em> 在任何这些循环范围之外的某个地方,但最好在将更改目标元素的innerHTML 的函数范围内。像这样的:

    let result = '';
    
    for (let i = 0; i < array.length; i++) {
      result += `<p>id: ${array[i].id}, x: ${array[i].x}</p>`;
    }
    
    element.innerHTML = result;
    

    但更适合你的情况。

    使用for 循环将我们带到了当今 Javascript 社区广泛遵循的一种做法:将 map 和 reduce(参见 Array#mapArray#reduce)应用于类型相似的元素的集合。使用这种方法,代码将如下所示:

    element.innerHTML = array.reduce((total, current) => `${total}<p>id: ${current.id}, x: ${current.x}</p>`, '');
    

    这可能看起来有点复杂,但效果完全相同。

    记住:如果你想添加到一个字符串(即连接),使用+=;如果您想替换它的值,请使用=

    【讨论】:

      猜你喜欢
      • 2016-09-07
      • 1970-01-01
      • 1970-01-01
      • 2011-08-16
      • 1970-01-01
      • 1970-01-01
      • 2021-10-13
      • 2019-12-17
      • 1970-01-01
      相关资源
      最近更新 更多