【问题标题】:jQuery Array.map and Object.keys() to map key of an array of objectjQuery Array.map 和 Object.keys() 映射对象数组的键
【发布时间】:2018-11-19 01:39:21
【问题描述】:

我这里有一个 JSON 文件:https://next.json-generator.com/api/json/get/E1qcwkNxr

我想用它来创建一个表。使用 jQuery 我得到响应数组并映射一些值来构建我的表格主体单元格:

        var data = $.getJSON('https://next.json-generator.com/api/json/get/E1qcwkNxr', function (response) {

            // map JSON to local arrays and define local vars
            var rows = response.map(function (r) {
                return [
                    r.age,
                    r.index,
                    r.registered,
                    r.balance,
                    r.eyeColor
                ];
            });
        });

我想对键做同样的事情,因为我想用这些数据构建 thead 单元格。有办法吗? Object.keys(response[0]);记录我对象中的所有键,我怎样才能只映射我想使用的键?

【问题讨论】:

  • 对不起,如果我误解了这个问题,但您是否试图将 Object.keys 限制为您在 map 函数中定义的那些(年龄、索引、注册、平衡、eyeColor?)
  • 是的,我需要这个东西
  • 我很好奇 - 如果您事先知道密钥,为什么需要致电 Object.keys?是为了减少键名的重复(在地图中,然后在构建中)?或者,其他原因?
  • @Jack 查看示例 JSON 文件:我有 12 个条目,我只想在此表中使用其中的五个。在另一个表中,我将使用同一文件的不同条目
  • 以下是我很快拼凑起来的一些 JavaScript:jsfiddle.net/jLe4ym2w - 你会使用 Object.keys 来生成表头吗? (编辑:渲染另一个表:jsfiddle.net/jLe4ym2w/1

标签: jquery arrays json object key


【解决方案1】:

要回答您关于 Object.keys 的问题,您需要针对已知集合进行过滤。

例如:

let keysToRender = ['index', 'age'];
Object.keys(response[0]).filter(key => { return ~keysToRender.indexOf(key) })

这是我汇总的一个解决方案(它基于我在 cmets 中发布给您的小提琴链接,但已清理),它使用 map。就个人而言,我更喜欢map 而不是$.each(对于这个问题),因为开销略少。

小提琴:http://jsfiddle.net/x3p79jfs/

编辑: 这是一个根据响应维护顺序的小提琴(正如您在另一条评论中提到的那样)-http://jsfiddle.net/x3p79jfs/1/

希望对你有帮助!

$.getJSON('https://next.json-generator.com/api/json/get/E1qcwkNxr', function(res) {
    // Extracts values from response
    const getModelFromKeys = (res, keys) => {
        return res.map(item => {
            return keys.map(key => {
                return item[key];
            });
        });
    };

    // Build template to append
    const buildTableFromModel = (header, body) => {
        let reducer = (arr, func, acc) => {
            return arr.reduce(func, acc);
        };

        let getTemplateCell = (template, item) => template + `<td>${item}</td>`;
        let getTemplateRow = (template, item) => template + `<tr>${reducer(item, getTemplateCell, ``)}</tr>`;
        
        return `
            <table><thead><tr>
            ${reducer(header, getTemplateCell, ``)}
            </tr></thead><tbody>
            ${reducer(body, getTemplateRow, ``)}
            </tbody></table>
        `
    };

    // Our expected set of keys to render (note first, last names which do not exist)
    let pii_table = ['age', 'index', 'first_name', 'last_name', 'registered', 'balance', 'eyeColor'];

    // Filter expected keys against ajax response
    // let filteredKeys = Object.keys(res[0]).filter(key => {
    //    return ~pii_table.indexOf(key);
    // });

    // Filter expected keys against ajax response
    let responseKeys = Object.keys(res[0]);
    let filteredKeys = pii_table.filter(key => {
        return ~responseKeys.indexOf(key);
    });

    // Build Table Model From Filtered Keys
    let firstTableModel = getModelFromKeys(res, filteredKeys);
    
    // Append table to Body
    document.body.innerHTML += buildTableFromModel(filteredKeys, firstTableModel);
});
td {
    padding: 3px;
    text-align: center;
}
thead {
    color: white;
    background-color: #777;
}
tr:nth-child(2n) {
    background-color: #ccc;
}
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;

【讨论】:

  • 谢谢你,它有效,我将在我未来的作品中使用你的例子。非常感谢!
【解决方案2】:

我建议您使用$.each() 而不是$.map()。像这样的:

var rows = [];
$.getJSON('https://next.json-generator.com/api/json/get/E1qcwkNxr', function (response) {
  $.each(response, function(i, x){
    var obj = {};
    var s = ["age", "index", "registered", "balance", "eyeColor"];
    $.each(x, function(k, v){
      if(s.indexOf(k) >= 0){
        obj[k] = v;
      }
    });
    rows.push(obj);
  });
});

现在您将拥有一个干净的对象数组,其中包含键和值。然后,您可以使用它来构建您的表格。

var $table = $("<table>");
$("<thead>").appendTo($table);
$("<tr>").appendTo($("thead", $table));
$.each(rows[0], function(key, val){
  $("<th>").html(key).appendTo($("thead tr", $table));
});
var $tbody = $("<tbody>").appendTo($table);
$.each(rows, function(ind, row){
  var $trow = $("<tr>").appendTo($tbody);
  $.each(row, function (item){
    $("<td>").html(item).appendTo($trow);
  });
});

工作示例:https://jsfiddle.net/Twisty/xv4kzy8L/

更新

如果您需要表格以特定的排序显示,您可以使用您的键名数组来执行此操作。然后按特定顺序显示结果:

var headers = ["age", "index", "registered", "balance", "eyeColor"];
var $table = $("<table>");
$("<thead>").appendTo($table);
$("<tr>").appendTo($("thead", $table));
$.each(headers, function(key, val){
  $("<th>").html(val).appendTo($("thead tr", $table));
});
var $tbody = $("<tbody>").appendTo($table);
$.each(rows, function(ind, row){
  var $trow = $("<tr>").appendTo($tbody);
  $.each(headers, function (k, i){
    $("<td>").html(row[i]).appendTo($trow);
  });
});

希望对您有所帮助。

【讨论】:

  • 我试试你的代码,但我希望键像内容行单元格一样排序(第一列中的年龄,第二列中的索引等等)。这样数组就不会像内容那样排序
  • @ufollettu 如果您愿意,您可以这样做。您可以确保它按照您喜欢的顺序存储,或者更好的是,按照您喜欢的顺序在表格中显示它。
猜你喜欢
  • 1970-01-01
  • 2018-04-07
  • 1970-01-01
  • 2019-04-28
  • 1970-01-01
  • 2017-08-25
  • 2012-05-30
  • 2016-09-21
  • 1970-01-01
相关资源
最近更新 更多