2014-10-30 111 views
2

我有这样的对象的数组,数组的清理接触对象(simplefied版本,实际的数组有更多的数据):创建联系人数据

[ 
    { 
     id: '1', 
     name: 'Joe', 
     description: 'Student', 
     locations: [ { 
      type: 'home', 
      value: '123' 
     } ] 
    }, 
    { 
     id: '1', 
     name: 'Joe', 
     description: 'Farmer', 
     locations: [ { 
      type: 'home', 
      value: '456' 
     } ] 
    }, 
    { 
     id: '1', 
     name: 'Joe', 
     description: '', 
     locations: [ { 
      type: 'home', 
      value: '123' 
     } ] 
    } 
] 

我如何使用JavaScript(lodash )创建以下内容? :

{ 
    id: '1', 
    name: 'Joe', 
    description: 'Farmer', 
    locations: [ { 
     type: 'home', 
     value: '123' 
    }, { 
     type: 'home', 
     value: '456' 
    } ] 
} 

目标是创建联系人数据数组的清理联系人对象。所以它需要替换单个属性,如名称和描述,以防它们为空。如果在de locations数组中找不到它,则推入位置等位置。使用_.merge我也得到了一定的成效,问题是,合并总是与去年值覆盖和犯规推新值,所以结果会是这样的:

{ 
    id: '1', 
    name: 'Joe', 
    description: '', 
    locations: [ { 
     type: 'home', 
     value: '123' 
    }] 
} 
+0

你如何确定描述应该是'农民',而不是'Stu凹痕'? – Sacho 2014-10-30 13:05:00

+0

这是我需要做的牺牲,没有办法指出优先权。 – Tristan 2014-10-30 13:06:35

回答

0

您有任何关于如何了很多尚未解决的问题处理冲突。

  • 应该最后一个属性覆盖前一个?你只想通过locations加入吗?
  • 是否仅通过id完成加入?
  • 如何确定locations的唯一性?是由type,value还是组合?

一旦你有这些问题的答案,你可以使用这样的事情:

// this will get you the items (from server/localstorage/whatever) 
var items = getItems(); 

// group items by id (assuming that's our grouping denominator 
var groupedItems = _.groupBy(items, 'id'); 

// then iterate through each item in group, and reduce them 
var results = _.map(_.values(groupdItems), function(item) { 
    var reduced = _.reduce(item, function(result, num, key) { 
     if (key === 'locations') { 
      // join everything together, we'll unique them later 
      result.locations = (result.locations || []).concat(num || []); 
     } 
     else { 
      // override all previous values for this key. 
      // change this to improve behavior 
      result[key] = num; 
     } 
     return result; 
    }, {}); 
    // reduce locations to unique locations only 
    // currently implemented by using JSON.stringified but could easily change 
    reduced.locations = _.uniq(reduced.locations, function(loc) { 
     return JSON.stringify(loc); 
    }); 
    return reduced; 
}); 

// results should now contains the transformed items. 
0

也许这应该是足够了:

function customMerge(obj1, obj2) { 
    for(var i in obj2) { 
     if(typeof(obj1[i]) === 'object' && obj1[i].push) { 
      for(var j in obj2[i]) { 
       obj1[i].push(obj2[i][j]); 
      } 
      obj1[i] = arrayUnique(obj1[i]); 
     } else { 
      obj1[i] = obj2[i]; 
     } 
    } 
} 

function arrayUnique(list, byKey) { 
    var newList = []; 
    var map = {}; 
    for(var i in list) { 
     var data = list[i]; 
     var id = list[i].id || JSON.stringify(data); 
     if(typeof(map[id]) === 'undefined') { 
      map[id] = data; 
     } else { 
      customMerge(map[id], data); 
     } 
    } 
    for(var i in map) { 
     newList.push(map[i]); 
    } 
    return newList; 
} 

这将返回你期待什么:

arrayUnique([ 
    { 
     id: '1', 
     name: 'Joe', 
     description: 'Student', 
     locations: [ { 
      type: 'home', 
      value: '123' 
     } ] 
    }, 
    { 
     id: '1', 
     name: 'Joe', 
     description: 'Farmer', 
     locations: [ { 
      type: 'home', 
      value: '456' 
     } ] 
    }, 
    { 
     id: '1', 
     name: 'Joe', 
     description: '', 
     locations: [ { 
      type: 'home', 
      value: '123' 
     } ] 
    } 
])