首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javascript按值合并数组中的对象

Javascript按值合并数组中的对象
EN

Stack Overflow用户
提问于 2010-08-26 16:05:51
回答 4查看 4.4K关注 0票数 0

在Javascript中,我有一个包含对象的数组,如下所示:

代码语言:javascript
复制
var arr = [
    {
        value_1: 0,
        value_2: 4,
        encounter_bits: {
            min_level: 8,
            max_level: 12,
            rarity: 20,
            conditions: [1, 5]
        }
    },
    {
        value_1: 1,
        value_2: 4,
        encounter_bits: {
            min_level: 5,
            max_level: 5,
            rarity: 20,
            conditions: [2, 9]
        }
    },
    {
        value_1: 0,
        value_2: 4,
        encounter_bits: {
            min_level: 8,
            max_level: 12,
            rarity: 5,
            conditions: [1, 5]
        }
    },
];

我需要合并具有相同min_level、max_level和条件的对象。合并后的对象将会将它们的稀有度相加。我还需要保留数组顺序。

因此arr和arr2将变成:

代码语言:javascript
复制
    arr[0] = {
        value_1: 0,
        value_2: 4,
        encounter_bits: {
            min_level: 8,
            max_level: 12,
            rarity: 25,
            conditions: [1, 5]
        }
    }

在大致相同的数据集中,这是在Python中完成的:

代码语言:javascript
复制
# Combine "level 3-4, 50%" and "level 3-4, 20%" into "level 3-4, 70%".
existing_encounter = filter(lambda enc: enc['min_level'] == encounter.min_level
                                    and enc['max_level'] == encounter.max_level,
                            encounter_bits)
if existing_encounter:
    existing_encounter[0]['rarity'] += encounter.slot.rarity
else:
    encounter_bits.append({
        'min_level': encounter.min_level,
        'max_level': encounter.max_level,
        'rarity': encounter.slot.rarity,
    })

我知道我可能需要对array.sort和array.splice做点什么,但是我想不通。实现这一目标的最有效方法是什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-08-26 19:57:47

这是我刚刚想出来的一些实验代码和它的原生javascript。

首先定义一个比较两个数组的函数。

代码语言:javascript
复制
function compareArrays( val_one, val_two ) {
  var arr_one = val_one, arr_two = val_two;

   if ( arr_one.length !== arr_two.length ) return false;

   for ( var i = 0; i < arr_one.length; i++ ) {
     if( arr_one[i] !== arr_two[i] ) return false;
   }  
  return true;
}

**还定义了一个合并两个对象的函数

代码语言:javascript
复制
function mergeObjects( obj_1, obj_2 ) {
  var a = obj_1, b = obj_2;

  for ( prop in b ) { 
    if ( !a[prop] ) {
      a[prop] = b[prop];
    }
    else if ( prop === 'encounter_bits' ) {
      a[prop]['rarity'] += b[prop]['rarity'];
    }
  }
  return a;
}

让我们遍历数组

代码语言:javascript
复制
for ( var i=0; i<arr.length; i++ ) {  // loop over the array that holds objects.
 if(arr[i] !== null){    // if object has not been used
  var _min = arr[i].encounter_bits.min_level,  
      _max = arr[i].encounter_bits.max_level,
      _con = arr[i].encounter_bits.conditions; //create variables that hold values you want to compare

for ( var c = 0; c < arr.length; c++ ) { /*  create an inner loop that will also traverse the array */

  if ( c !== i && arr[c] !== null ) {   // if inner loop is not on current loop index 
    if ( _min === arr[c].encounter_bits.min_level &&
        _max === arr[c].encounter_bits.max_level &&
        compareArrays(_con, arr[c].encounter_bits.conditions)  
      ) 
        {
         var newObject = mergeObjects(arr[i], arr[c]);
         arr[i] = newObject;     
         arr[c] = null; 
         }
        }

    }
  }       
}

如果可以的话,请告诉我。

票数 0
EN

Stack Overflow用户

发布于 2010-08-26 20:07:59

我还没有测试过它,但它应该给出了基本的想法。不使用拼接或排序。

代码语言:javascript
复制
// Collect members that have same min-max levels in one array.
// this array is saved in a map keyed by a string made up of min-max levels
var m = {};
for(var i=0; i<arr.length; i++)
{
    var a = arr[i];
    tag = ''+a.encounter_bits.min_level+'-'+a.encounter_bits.max_level);
    if(m[tag]){
        m[tag].push(i);
    }else {
        m[tag] = [i]
    }
}

// for each element of map, calculate sum of rarities
// set the rarity of all member in that element of map to sum of rarities
for(var i in m){
    var candidates = m[i];
    var r = 0;
    for(var j=0; j<candidates.length; j++){
      r += candidates[j].encounter_bits.rarity;
    }
    for(var j=0; j<candidates.length; j++){
       candidates[j].encounter_bits.rarity = r;
    }            
 }
票数 0
EN

Stack Overflow用户

发布于 2010-08-26 21:21:33

下面是用代码编写的名称空间良好且自包含的解决方案。它没有使用像forEachfilter这样的“现代”(可能是不可用的)特性。它在说完和做完之后清理无效的记录,而不是在过程进行时删除活动数组中的项。如果您想要更改识别重复项的方式或合并对象的方式,也可以非常容易地进行修改。

在pastie,here上有一个注释版本(带有示例和精简版本)。

代码语言:javascript
复制
(function (global, ns) {
function mergeRecordsAndCleanUp(arr) {
  var rec, dupeIndices, foundDupes;
  for(var idx=0, len=arr.length; idx<len-1; ++idx) {
    rec = arr[idx];
    if (rec===null) continue;
    dupeIndices = findDupeIndices(rec, arr.slice(idx+1), idx+1);
    if (dupeIndices.length===0) continue;
    foundDupes = true;
    processDupes(rec, dupeIndices, arr);
  }
  if (foundDupes) cleanUpArray(arr);
}
function cleanUpArray(arr) {
  for (var idx=0, len=arr.length; idx<len; ++idx) {
    if (arr[idx]===null) arr.splice(idx--, 1);
  }
}
function processDupes(rec, dupeIndices, arr) {
  var dupeRealIdx, dupeRec;
  for (var dupeIdx=0, dupesLen=dupeIndices.length; dupeIdx<dupesLen; ++dupeIdx) {
    dupeRealIdx = dupeIndices[dupeIdx];
    dupeRec = arr[dupeRealIdx];
    updateRecord(rec, dupeRec);
    arr[dupeRealIdx] = null;
  }
}
function findDupeIndices(rec, arr, offset) {
  var other, result = [];
  for (var idx=0, len=arr.length; idx<len; ++idx) {
    other = arr[idx];
    if (other===null) continue;
    if (isDupe(rec, other)) result.push(idx+offset);
  }
  return result;
}
function identicalArrays(arr0, arr1) {
  if (arr0.length!==arr1.length) return false;
  for (var idx=0, len=arr0.length; idx<len; ++idx) {
    if (arr0[idx]!==arr1[idx]) return false;
  }
  return true;
}
function isDupe(original_record, candidate_record) {
  var orec_bits = original_record.encounter_bits
    , crec_bits = candidate_record.encounter_bits;
  return (crec_bits.min_level===orec_bits.min_level && crec_bits.max_level===orec_bits.max_level) 
    && (identicalArrays(crec_bits.conditions, orec_bits.conditions));
}
function updateRecord(rec, dupe) {rec.encounter_bits.rarity += dupe.encounter_bits.rarity}
global[ns] = {
  npup: mergeRecordsAndCleanUp
};
})(this, 'npup'/* sweet namespace eh */);
// npup.npup(arr);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3573165

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档