Node.js + objectArray

时间:2014-04-09 07:22:26

标签: javascript node.js

在我的节点应用程序中,我必须从另一个对象数组构造一个对象数组。

将我的对象数组视为......

 levels: [
{
country_id: 356,
country_name: "aaa",
level0: "bbbb",
level1: "cccc",
level2: "dddd",
level3: "eeee",
level4: "fffff"
},
{
country_id: 356,
country_name: "aaaa",
level0: "bbbb",
level1: "cccc",
level2: "dddd",
level3: "eeee",
level4: "gggg"-----------> here is the differnce..
}
]

如果对于相同的id,上面的任何一个是不同的,我必须使它成为一个数组,并且应该是1个id的单个条目。

所以我想要的是:

 levels: [
    "356":{        
    country_name: "aaa",
    level0: "bbbb",
    level1: "cccc",
    level2: "dddd",
    level3: "eeee",
    level4: ["fffff","gggg"]
    }]

但是我无法以正确的方式去做。请帮我解决这个问题。谢谢。

3 个答案:

答案 0 :(得分:2)

注意:请注意,此程序假定级别中只有两次重复。

var obj = {
    levels: [{
        country_id: 356,
        country_name: "aaa",
        level0: "bbbb",
        level1: "cccc",
        level2: "dddd",
        level3: "eeee",
        level4: "fffff"
    }, {
        country_id: 356,
        country_name: "aaa",
        level0: "bbbb",
        level1: "cccc",
        level2: "dddd",
        level3: "eeee",
        level4: "gggg"
    }]
};

obj.levels = obj.levels.reduce(function(result, current) {
    result[current.country_id] = result[current.country_id] || {};
    var temp_result = result[current.country_id];
    for (var key in current) {
        if (temp_result.hasOwnProperty(key) === false) {
            temp_result[key] = current[key];
        } else if (temp_result[key] !== current[key]) {
            temp_result[key] = [temp_result[key], current[key]];
        }
    }
    return result;
}, {})

console.log(obj);

<强>输出

{ levels: 
   { '356': 
      { country_id: 356,
        country_name: 'aaa',
        level0: 'bbbb',
        level1: 'cccc',
        level2: 'dddd',
        level3: 'eeee',
        level4: ['fffff', 'gggg'] } } }

这是一个通用的解决方案,

obj.levels = obj.levels.reduce(function(result, current) {
    result[current.country_id] = result[current.country_id] || {};
    var temp_result = result[current.country_id],
        toString = Object.prototype.toString;
    for (var key in current) {
        if (temp_result.hasOwnProperty(key) === false) {
            temp_result[key] = current[key];
        } else if (toString.call(temp_result[key]) === "[object Array]") {
            if (temp_result[key].every(function(currentItem) {
                return currentItem !== current[key];
            })) {
                temp_result[key].push(current[key]);
            }
        } else if (temp_result[key] !== current[key]) {
            temp_result[key] = [temp_result[key], current[key]];
        }
    }
    return result;
}, {});

答案 1 :(得分:1)

在以下示例中,我使用underscore js

var obj = {
    levels: [
    {
        country_id: 356,
        country_name: "aaa",
        level0: "bbbb",
        level1: "cccc",
        level2: "dddd",
        level3: "eeee",
        level4: "fffff"
    },
    {
        country_id: 356,
        country_name: "aaaa",
        level0: "bbbb",
        level1: "cccc",
        level2: "dddd",
        level3: "eeee",
        level4: "gggg"
    }]
};

var transform = function (obj) {

    // a temporary object so we can do lookups more quicker
    var tmpObj = {};

    // merge two elements as described in Question
    var merge = function (dst, src) {
        _.each(src, function (val, key) {
            if (key.indexOf('level') === -1) { // merge only level keys
                return;
            }
            var dstVal = dst[key];
            if (!dstVal) { // key & val are not in the dst object
                dst[key] = val; 
            } else if (dstVal !== val && !_.isArray(dstVal)) { // key is present but values differ
                dst[key] = [dstVal, val];
            } else if (_.isArray(dstVal) && _.indexOf(dstVal, val) === -1) { // key is present and the val is not in the array
                dst[key].push(val);
            }
        });
    };

    // iterate through all the elements and merge them
    _.each(obj.levels, function (el) {
        var obj = tmpObj[el.country_id];
        if (obj) {
            merge(obj, el);
        } else {
            tmpObj[el.country_id] = el;
        }
    });

    // map the elements back
    obj.levels = _.map(tmpObj, function (el) { return el; });
};

transform(obj);

var resultObj = _.map(tmpObj, function (el) { return el; }); // the tmp object is transformed back to the desired format

输出:

enter image description here

答案 2 :(得分:1)

看起来你已经接受了答案,但我也会发布我的答案。它具有以下优点:

  1. 通过创建它们的浅层副本来保留原始级别对象。
  2. 它使用相同的键与对象相交,并且不会添加重复的值。
  3. 以下是代码:

    var levels = [
    {
      country_id: 356,
      country_name: "aaa",
      level0: "bbbb",
      level1: "cccc",
      level2: "dddd",
      level3: "eeee",
      level4: "fffff"
    },
    {
      country_id: 356,
      country_name: "aaaa",
      level0: "bbbb",
      level1: "cccc",
      level2: "dddd",
      level3: "eeee",
      level4: "gggg"
    },
    {
      country_id: 356,
      country_name: "aaaa",
      level0: "bbbb",
      level1: "cccd",
      level2: "dddd",
      level3: "eeee",
      level4: "gggg"
    },
    {
      country_id: 354,
      country_name: "aaaa",
      level0: "bbbb",
      level1: "cccc",
      level2: "dddd",
      level3: "eeee",
      level4: "gggg"
    }
    ];
    
    var mergedLevels = {};
    
    function shallowCopyWithoutId(object) {
      var o = {},
          i;
    
      for (i in object) {
        if (object.hasOwnProperty(i) && i !== 'country_id') {
          o[i] = object[i];
        }
      }
    
      return o;
    }
    
    function merge(o1, o2) {
      var i;
    
      for (i in o1) {
        if (o1.hasOwnProperty(i) && o2.hasOwnProperty(i)) {
            if (o1[i] instanceof Array) {
              if (o1[i].indexOf(o2[i]) === -1) o1[i].push(o2[i]);
            } else if (o1[i] !== o2[i]) {
              o1[i] = [o1[i], o2[i]];
            }
        }
      }
    }
    
    var i, level;
    
    for (i = 0; i < levels.length; i++) {
      level = levels[i];
      if (!mergedLevels.hasOwnProperty(level.country_id)) {
        mergedLevels[level.country_id] = shallowCopyWithoutId(level);
      } else {
        merge(mergedLevels[level.country_id], level);
      }
    }
    
    console.log(mergedLevels);
    

    输出:

    { '354':
       { country_name: 'aaaa',
         level0: 'bbbb',
         level1: 'cccc',
         level2: 'dddd',
         level3: 'eeee',
         level4: 'gggg' },
      '356':
       { country_name: [ 'aaa', 'aaaa' ],
         level0: 'bbbb',
         level1: [ 'cccc', 'cccd' ],
         level2: 'dddd',
         level3: 'eeee',
         level4: [ 'fffff', 'gggg' ] } }