2016-10-05 34 views

回答

3

我做到了通過寫入該功能(基本上覆制鍵成一個結構,如果它不存在,並將其添加到最終的陣列):

<cffunction name="RemoveDuplicatesFromObjectArray"> 
    <cfargument name="objs" type="array"> 
    <cfargument name="key" type="string"> 
    <cfscript> 
     var keys ={}; 
     var result = []; 
     for (var obj in arguments.objs) 
     { 
      if (not StructKeyExists(keys, obj[arguments.key])) 
      { 
       ArrayAppend(result, obj); 
       keys[obj[arguments.key]] = true; 
      } 
     } 
    </cfscript> 

    <cfreturn result> 
</cffunction> 

,並調用它像這樣:

<cfset arr = [{ 
        "EXPENSEREPORTID": 129591, 
        "EXPENSELINEITEMID": 602684, 
        "DOLLARSBEFORE": 8.1000000000, 
        "DOLLARSAFTER": 5.4000000000 
       }, { 
        "EXPENSEREPORTID": 129591, 
        "EXPENSELINEITEMID": 602684, 
        "DOLLARSBEFORE": 8.1000000000, 
        "DOLLARSAFTER": 5.4000000000 
       }]> 
<Cfdump var="#RemoveDuplicatesFromObjectArray(arr,'EXPENSEREPORTID')#"> 
2

只是爲了好玩,因爲你是在CF11 +,我還以爲因爲你可能有興趣看到一個替代我會ArrayFilter()做,但你的回答是偉大的(我看到Leigh修復了幾個問題)。你建立一個結構來匹配鍵,並同時修改返回數組。

使用結構作爲索引遠遠超過其他可能在更大的數組上使用ArrayFind()的方法。什麼是甚至更​​好實際上是從一開始就在數組上構建一個結構。以這種方式,你不必擔心唯一性。如果訂單很重要,則可以使用LinkedHashMaps。

這裏是例如: http://trycf.com/gist/df2fad58219163b7b64c9523b8383921/acf11

<cfscript> 

data = [ 
    { 
     dollarsafter : 5.4 
     , dollarsbefore : 8.1 
     , expenselineitemid : 602684 
     , expensereportid : 129591 
    } 
    ,{ 
     dollarsafter : 5.4 
     , dollarsbefore : 8.1 
     , expenselineitemid : 602684 
     , expensereportid : 129593 
    } 
    ,{ 
     dollarsafter : 5.4 
     , dollarsbefore : 8.1 
     , expenselineitemid : 602684 
     , expensereportid : 129591 
    } 
]; 

function doFilter(data){ 
    var index = {}; 
    return data.filter(function(item){ 
     return ! itemFoundInIndexByKey(item, index, item['expensereportid']); 
    }); 
} 

function itemFoundInIndexByKey(item, index, key){ 
    var foundIt = index.keyExists(key); 
    if(! foundIt){ 
     index[ key ] = ''; 
    } 
    return foundIt; 
} 

writeDump(doFilter(data)); 
</cfscript> 

獎金示例簡明碼(不使用可重複使用的邏輯爲過濾器): http://trycf.com/gist/e3ae76877bdc0809f02ee3333d51f8ae/acf11?theme=monokai

<cfscript> 

data = [ 
    { 
     dollarsafter : 5.4 
     , dollarsbefore : 8.1 
     , expenselineitemid : 602684 
     , expensereportid : 129591 
    } 
    ,{ 
     dollarsafter : 5.4 
     , dollarsbefore : 8.1 
     , expenselineitemid : 602684 
     , expensereportid : 129593 
    } 
    ,{ 
     dollarsafter : 5.4 
     , dollarsbefore : 8.1 
     , expenselineitemid : 602684 
     , expensereportid : 129591 
    } 
]; 

function filterDuplicateObjectArrayByKey(required array data, required string key, index = {}){ 
    return data.filter(function(item){ 
     if(! index.keyExists(item[ key ])){ 
      index[ item[ key ] ] = ''; 
      return true; 
     } 
     return false; 
    }); 
} 

writeDump(filterDuplicateObjectArrayByKey(data, 'expensereportid')); 
</cfscript> 
+0

這很酷,我不知道新的.reduce()函數。謝謝! –

+0

@SajjanSarkar我切換到了Array.filter()而不是reduce,因爲這更像是一個過濾器。它也有助於使其更加簡潔。值得注意的是,你不必使用單獨的函數,但這是爲了證明它。 –