在JavaScript中将类似对象组合在一起

时间:2014-05-23 18:53:59

标签: javascript jquery json

我有一些javascript正在获取一些JSON,我试图将某些信息行组合在一起用于表格。

JSON如下所示:

[{"Code":"12345","Name":"foo","Service":"Payments"},
{"Code":"12345","Name":"foo","Service":"Marketing"},
{"Code":"23456","Name":"bar","Service":"Payments"},
{"Code":"23456","Name":"bar","Service":"Development"},
{"Code":"34567","Name":"baz","Service":"Marketing"}]

除了一个字段Service之外,基本上某些行彼此共享完全相同的信息。

我的想法是尝试将每一行变成一个对象,我可以更新或与另一个共享相同Code的对象合并。

该对象和代码如下所示:

function CustObj(code,name,hasPay,hasMarket,hasDev) {
  this.code = code;
  this.name = name;
  this.hasPay = hasPay;
  this.hasMarket = hasMarket;
  this.hasDev = hasDev;
}

function formatData(data) {
  var formatedData = [];
  for (var key in data) {
    var customer = new CustObj(data[key].Code,data[key].Name);
    switch (data[key].Service) {
      case 'Payments':
        customer.hasPay = true;
        break;
      case 'Marketing':
        customer.hasMarket = true;
        break;
      case 'Development':
        customer.hasDev = true;
        break;
    }
    formatedData.push(school);
  }
}

问题是我想为每个唯一的Code设置一个对象,但是根据Service有正确数量的标记,但我还没有想出如何做到这一点。我正在寻找像$.extend(formatedData,customer)之类的东西来合并对象,但我似乎无法找到正确的逻辑来定位我试图合并的两个对象。

有关如何实现这一目标的任何想法?

2 个答案:

答案 0 :(得分:2)

您可以处理重复数组并创建一个新数组,其中“Service”属性是共享相同CodeName的服务数组:

var data = [
    {"Code":"12345","Name":"foo","Service":"Payments"},
    {"Code":"12345","Name":"foo","Service":"Marketing"},
    {"Code":"23456","Name":"bar","Service":"Payments"},
    {"Code":"23456","Name":"bar","Service":"Development"},
    {"Code":"34567","Name":"baz","Service":"Marketing"}
];

function mergeServices(data) {
    var result = [], item, match, found;
    // for each array item
    for (var i = 0; i < data.length; i++) {
        item = data[i];
        found = false;
        for (var j = 0; j < result.length; j++) {
            // see if we have a dup of a previously existing item
            if (item.Code == result[j].Code && item.Name == result[j].Name) {
                // just add the Service name to the array of the previous item
                result[j].Service.push(item.Service);
                found = true;
                break;
            }
        }
        if (!found) {
            // copy the current row (so we can change it without changing original)
            var newItem = {};
            for (var prop in item) {
                newItem[prop] = item[prop];
            }
            // convert service to an array
            newItem.Service = [newItem.Service];
            result.push(newItem);
        }
    }
    return result;
}

var output = mergeServices(data);

产生这个output

[
    {"Code":"12345","Name":"foo","Service":["Payments","Marketing"]},
    {"Code":"23456","Name":"bar","Service":["Payments","Development"]},
    {"Code":"34567","Name":"baz","Service":["Marketing"]}
]

工作jsFiddle:http://jsfiddle.net/jfriend00/6rU2z/

答案 1 :(得分:2)

在创建客户时,您可以将它们添加到地图(对象)中,以便代码可以引用它们。您只能创建尚未在地图中的客户。对于您获得的每一行或创建相应的客户并设置相应的标志。

function formatData(data) {
    var customerMap = {};
    $(data).each(function(index, elem){

        // Get the customer if it is already in the map, else create it
        var customer = customerMap[elem.Code];
        if(!customer) {
            customer = new CustObj(elem.Code, elem.Name);
            customerMap[elem.Code] = customer;
        }

        // Add flags as appropiate
        switch (elem.Service) {
            case 'Payments':
                customer.hasPay = true;
                break;
            case 'Marketing':
                customer.hasMarket = true;
                break;
            case 'Development':
                customer.hasDev = true;
                break;
        }
    });

    // Convert map to array
    var formatedData = [];
    for(var code in customerMap){
        formatedData.push(customerMap[code]);
    }
}

function CustObj(code,name) {
    this.code = code;
    this.name = name;
    this.hasPay = false;
    this.hasMarket = false;
    this.hasDev = false;
}

编辑我创造了一个演示这个

的小提琴

<强> JSFiddle