【问题标题】:javascript map array and return objectjavascript映射数组和返回对象
【发布时间】:2018-04-10 17:33:57
【问题描述】:

我有以下 JSON 数组:

[
  [22, "Data Structures", 45],
  [23, "English", 52],
  [22, "English", 51],
  [26, "Data Structures", 72],
  [23, "Data Structures", 61],
  [26, "English", 81]
]

其中每个数组包含一个 ID、主题和获得的标记。

如何使用 JavaScript map() 函数获取响应?:

{
  "Data Structures" : "26",
  "English" : "26"
}

这意味着它应该返回得分最高的学生的 id。

【问题讨论】:

  • 请添加您尝试过的内容。
  • 您只想使用map 还是使用其他方式?
  • 我们可以做任何其他逻辑,我试图使用 for 循环,但我猜它需要两个循环

标签: javascript associative-array


【解决方案1】:

由于您使用的是数组,因此如果您愿意,可以使用Array.prototype.reduce。此解决方案循环遍历数组中的每个项目,并根据当前记录是否高于最后记录的记录,将当前记录保存到提供的累加器(在本例中为{}),从而产生以下对象。

{
  "Data Structures": { "id": 26, "score": 72 },
  "English": { "id": 26, "score": 81 }
}

如果您想进一步简化为科目和表现最好的学生的 ID,您可以遍历对象键并将值设置为 id。

var myArray = [
    [22, "Data Structures", 45],
    [23, "English", 52],
    [22, "English", 51],
    [26, "Data Structures", 72],
    [23, "Data Structures", 61],
    [26, "English", 81]
];

var findMaxScores = function(highScores, entry) {
  var currentId = entry[0];
  var currentSubject = entry[1];
  var currentScore = entry[2];
  var record = highScores[currentSubject];

  if (record === undefined || currentScore > record.score) {
      highScores[currentSubject] = {
        id: currentId,
        score: currentScore,
      };
  }
  return highScores;
}

var highScores = myArray.reduce(findMaxScores, {});

Object.keys(highScores).forEach(subject => highScores[subject] = highScores[subject].id);

console.log(highScores);

【讨论】:

  • Index 0 是学生ID,但问题想要最高分(索引2)。您需要跟踪主题并将最大值与 ID 一起存储。您缺少将 ID/分数转换为 ID 的步骤。见:jsfiddle.net/cmkpqzcs
  • 好收获。我假设最后一个索引是一个 id 出于某种原因
【解决方案2】:

我会先对数据进行排序,然后将每个条目的第一个类别添加到地图中。

var scoringData = [
  [22, "Data Structures", 45],
  [23, "English", 52],
  [22, "English", 51],
  [26, "Data Structures", 72],
  [23, "Data Structures", 61],
  [26, "English", 81]
];

var sorters = [ { key : 1, dir : 1 }, { key : 2, dir : -1 } ];
console.log(retrieveHighest(scoringData, sorters, 1, 0));

function retrieveHighest(data, sorters, categoryIndex, targetIndex) {
  var sorter = multiSorter.apply(null, sorters);
  return data.sort(sorter).reduce((result, item) => {
    if (result[item[categoryIndex]] === undefined) {
      result[item[categoryIndex]] = item[targetIndex];
    }
    return result;
  }, {});
}

function multiSorter(sorters) {
  var tailArgs = Array.prototype.slice.call(arguments, 1);
  return function(a, b) {
    var key = typeof sorters === 'object' ? sorters.key : sorters;
    var dir = typeof sorters === 'object' ? sorters.dir : 1;
    var aV = a[key], bV = b[key];
    var equality = (typeof aV === 'string' ? aV.localeCompare(bV) : aV - bV) * dir;
    if (equality === 0 && arguments.length > 1) {
      return multiSorter.apply(null, tailArgs)(a, b);
    }
    return equality;
  };
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

【讨论】:

    【解决方案3】:

    您可以使用Map 收集最大值然后渲染对象。

    第一部分迭代给定数据并将数组破坏为idsubjectscore

    然后检查是否存在对象,如果存在,则将分数或零与实际分数进行比较。

    如果检查是true,设置/更新地图。

    为了获得结果,所有条目都取自映射,并为每个条目返回一个对象,其中主题为键,id 为值。

    后来,Object.assign 从多个对象创建了一个对象。

    var array = [[22, "Data Structures", 45], [23, "English", 52], [22, "English", 51], [26, "Data Structures", 72], [23, "Data Structures", 61], [26, "English", 81]],
        map = new Map,
        result;
    
    array.forEach(([id, subject, score]) => {
        if ((map.has(subject) && map.get(subject).score || 0) < score) {
            map.set(subject, { id, score });
        }
    });
    
    result = Object.assign(
        ...[...map.entries()].map(([subject, { id }]) => ({ [subject]: id }))
    );
    
    console.log(result);

    【讨论】:

    • 这似乎过于复杂,不包括任何解释。 OP 可能会复制并粘贴此解决方案,但永远无法弄清楚它是如何工作的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    • 2018-05-30
    • 2021-02-17
    • 2020-11-09
    • 1970-01-01
    • 2022-01-23
    相关资源
    最近更新 更多