在JavaScript或jQuery中比较两种不同的数组类型

4

我有两种不同的数组类型。其中一种是字符串数组,另一种是对象数组。

stringArray = ["P1", "P2", "P3"];
objectArray = [{ P: "P1", PO: 5}, { P: "P3", PO: 10}];

我希望将对象数组放入表格中。字符串数组元素必须是表头。
如果对象数组具有 P == "P1",则将5放入单元格。否则,在行中放置空单元格。
我尝试过这个,但是会放置多个空单元格。
这是我的代码 "tKeys" = stringArray, "Ciktilar" = objectArray
var baslikEklendiMi = false;
var satirEkle = function(CalismaTipi, Ciktilar, tKeys)
{
    var satir = '<td>' + CalismaTipi + '</td>';
    $.each(tKeys, function (i, val) {
        if (baslikEklendiMi == false) {
            $("#tblBaslik").append("<th>" + val+ "</th>");
        }

        $.each(Ciktilar, function (j, obj) {
            if (val == obj.P) {
                satir += '<td><b>' + obj.PO+ '</b></td>';
            }
            else {
                satir += '<td></td>';
            }
        });
    });

    baslikEklendiMi = true;
    $("#tblListe").append('<tr>' + satir + '</tr>');
}

不清楚所期望的结果是什么。"将空单元格放入行中"是什么意思?请在 jsfiddle.net 或 plunker 上提供一个 [mcve] 示例,包含样本数据和期望的最终结果样本。 - charlietfl
@charlietfl 你说得对。下次我会遵循指示。 - Hakkı
3个回答

1

我想使用一个我经常使用的工具从对象或多个对象的数组中生成表格HTML。因此,下面的代码将为您生成表格。通用的tableMaker函数接受在第一个参数中提供的一个对象数组或多个对象的数组。由于这些键用于创建表头(如果第二个参数设置为true),并且值用于创建每一行,因此所有对象应该具有相同的键(属性)。它将返回一个HTML表格文本。您可以在here查看使用较小数据大小的tableMaker函数的工作方式。您还可以使用一些示例和简单数据进行练习。

var tableMaker = (o,h) => {var keys = o.length && Object.keys(o[0]),
                           rowMaker = (a,t) => a.reduce((p,c,i,a) => p + (i === a.length-1 ? "<" + t + ">" + c + "</" + t + "></tr>"
                                                                                           : "<" + t + ">" + c + "</" + t + ">"),"<tr>"),
                           rows = o.reduce((r,c) => r + rowMaker(keys.reduce((v,k) => v.concat(c[k]),[]),"td"),h ? rowMaker(keys,"th") : []);
                           return rows.length ? "<table>" + rows + "</table>" : "";
                          },
   stringArray = ["P1", "P2", "P3"],
   objectArray = [{ P: "P1", PO: 5}, { P: "P3", PO: 10}],
   tableObject = stringArray.reduce((p,c) => {var fo = objectArray.find(f => f.P == c);
                                               p[c] = fo ? fo.PO : "";
                                               return p;} ,{}),
     tableHTML = tableMaker([tableObject],true);
document.write(tableHTML);
console.log(tableHTML);


谢谢你的解决方案。这个也可以,但是@bloodyKnuckles的解决方案对我来说更容易些。 - Hakkı

1
你需要像这样更改你的代码:

你必须像这样更改你的代码:

var satirEkle = function(CalismaTipi, Ciktilar, tKeys) {
    var satir = '<td>' + CalismaTipi + '</td>';
    $.each(tKeys, function (i, val) {
        if (baslikEklendiMi == false) {
            $("#tblBaslik").append("<th>" + val+ "</th>");
        }
        var emptyCell = false;
        $.each(Ciktilar, function (j, obj) {
            if (val == obj.P) {
                satir += '<td><b>' + obj.PO+ '</b></td>';
            }
            else {
                emptyCell = true;
            }
        });

        if (emptyCell) {
            satir += '<td>-</td>';
        } 
    });

    baslikEklendiMi = true;
    $("#tblListe").append('<tr>' + satir + '</tr>');
}

你应该在空单元格中添加一个字符,以获得更友好的布局。
一个好的选择是使用空的html空间&nbsp;
希望这能帮助到你。

1
得到类似以下内容:
|--|--|--|--|
|ct|P1|P2|P3|
|--|--|--|--|
|??|5 |  |10|
|--|--|--|--|

您的代码需要进行五项更改:

1)第7行(下面):实例化emptyCell,将其赋值为false

2)第9行:添加$("#tblBaslik").append("<th>ct</th>")以考虑CalismaTipi列,

3)第25-27行:将satir += '<td></td>'移至Ciktilar循环之外。

4)第22行:将emptyCell赋值为true

5)第18-19行:重置emptyCell并退出Ciktilar循环。

var stringArray  = ["P1", "P2", "P3"];
var objectArray  = [{ P: "P1", PO: 5}, { P: "P3", PO: 10}];

var baslikEklendiMi = false;
var satirEkle = function(CalismaTipi, Ciktilar, tKeys)
{
    var emptyCell = false;                                // Line 7
    var satir = '<td>' + CalismaTipi + '</td>';
    $("#tblBaslik").append("<th>ct</th>");                // Line 9
    $.each(tKeys, function (i, val) {
        if (baslikEklendiMi === false) {
            $("#tblBaslik").append("<th>" + val+ "</th>");
        }

        $.each(Ciktilar, function (j, obj) {
            if (val == obj.P) {
                satir += '<td><b>' + obj.PO+ '</b></td>';
                emptyCell = false;                         // Line 18
                return false;
            }
            else {
              emptyCell = true;                            // Line 22
            }
        });
        if (emptyCell) {                                   // Line 24
            satir += '<td></td>';
        }
    });

    baslikEklendiMi = true;
    $("#tblListe").append('<tr>' + satir + '</tr>');
};
satirEkle('??', objectArray, stringArray);

你需要将 satir += '<td></td>'; 移动到 Ciktilar 循环之外的原因是因为 stringArray 列表与 objectArray 列表不直接对应。 你想要检查所有的 stringArray 元素以找到匹配项,如果在检查完所有的 stringArray 元素后没有匹配项,则写入一个空单元格。 因此,不要在循环中写入 satir,而是设置一个 emptyCell 标志,并在循环后检查该标志。

JSBin 示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接