GroupBy在JavaScript中对JSON数据进行分组并填充在optgroup上

use*_*276 11 jquery json optgroup

我有点失落.我得到这个JSON:

[{
    "id": "210",
    "name": "Name 1",
    "category": "Category 1"
}, {
    "id": "187",
    "name": "Name 2",
    "category": "Category 1"
}, {
    "id": "186",
    "name": "Name 3",
    "category": "Category 1"
}, {
    "id": "185",
    "name": "Name 4",
    "category": "Category 1"
}, {
    "id": "184",
    "name": "Name 5",
    "category": "Category 1"
}, {
    "id": "183",
    "name": "Name 6",
    "category": "Category 1"
}, {
    "id": "182",
    "name": "Name 7",
    "category": "Category 1"
}, {
    "id": "181",
    "name": "Name 8",
    "category": "Category 2"
}, {
    "id": "180",
    "name": "Name 9",
    "category": "Category 3"
}, {
    "id": "178",
    "name": "Name 10",
    "category": "Category 2"
}]
Run Code Online (Sandbox Code Playgroud)

我想把所有这些都放在带有选项和optgroups的选择中.实际上,optgroup应该是category

我想要这样的东西:

<select name="products" class="product" id="product">
<optgroup label="Category 1">
    <option value="210">Name 1</option>
    <option value="187">Name 2</option>
    <option value="186">Name 3</option>
    <option value="185">Name 4</option>
    ...
</optgroup>
<optgroup label="Category 2">
    <option value="181">Name 8</option>
    <option value="178">Name 10</option>
</optgroup>
<optgroup label="Category 3">
    <option value="180">Name 9</option>
</optgroup>
Run Code Online (Sandbox Code Playgroud)

今天我只是做了这个,因为我挣扎太多了:

$(document).ready(function () {
    $.getJSON("5.php", {
        val: $(this).val()
    }, function (data) {
        $.each(data, function (i, item) {
            $("<option/>").attr("value", item.id).append(item.name).appendTo("optgroup");
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

你可以看到没有optgroup :)有没有办法做到这一点?我也可以修改我的JSON,如果它可以使它更容易.

谢谢你的帮助.

小智 16

假设optgroups已经存在,请更改此...

.appendTo("optgroup")
Run Code Online (Sandbox Code Playgroud)

对...

.appendTo("optgroup[label='" + item.category + "']");
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/FG9Lg/


如果它们不存在,则需要创建它们,但我建议重构您的JSON响应,以使每个项目嵌套在正确的类别下.

像这样...

{
    "Category 1":[
        {"id": "210","name": "Name 1"},
        {"id": "187","name": "Name 2"},
        {"id": "186","name": "Name 3"},
        {"id": "185","name": "Name 4"},
        {"id": "184","name": "Name 5"},
        {"id": "183","name": "Name 6"},
        {"id": "182","name": "Name 7"}
    ],
    "Category 2":[
        {"id": "181","name": "Name 8"},
        {"id": "178","name": "Name 10"}
    ],
    "Category 3": [
        {"id": "180","name": "Name 9"}
    ]
}
Run Code Online (Sandbox Code Playgroud)

所以你可以这样做:

var product = $('#product');

$.each(data, function (key, cat) {
    var group = $('<optgroup>',{label:key});

    $.each(cat,function(i,item) {
        $("<option/>",{value:item.id,text:item.name})
            .appendTo(group);
    });

    group.appendTo( product );
});
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/FG9Lg/1/


Abd*_*nim 16

如果我是你,我会使用一个名为Underscore的小型库来分组以更容易的方式返回的数据.

请参阅下面的代码,您可能还会看到此实时演示:

var groupData = _.groupBy(data, function (obj) {
    return obj.category;
});

var optGroups = [];
for (var key in groupData) {
    if (groupData.hasOwnProperty(key)) {
        var optGroup = $("<optgroup></optgroup>");
        optGroup.attr("label", key);
        var currentGroup = groupData[key];
        for (var i = 0; i < currentGroup.length; i++) {
            $("<option />").attr("value", currentGroup[i].id).html(currentGroup[i].name).appendTo(optGroup);
        }
        optGroups.push(optGroup);
    }
}

for(var i = 0; i < optGroups.length; i++) {
    $("#products").append(optGroups[i]);
}
Run Code Online (Sandbox Code Playgroud)

如果您对使用Underscore库犹豫不决,可以考虑以下groupBy功能:

var groupBy = function(array, predicate) {
    var grouped = {};
    for(var i = 0; i < array.length; i++) {
        var groupKey = predicate(array[i]);
        if (typeof(grouped[groupKey]) === "undefined")
            grouped[groupKey] = [];
        grouped[groupKey].push(array[i]);
    }

    return grouped;
}
Run Code Online (Sandbox Code Playgroud)

用法:

var groupData = groupBy(data, function (obj) {
    return obj.category;
});
Run Code Online (Sandbox Code Playgroud)