2017-02-15 82 views
1

我有一個JavaScript陣列,像這樣:刪除重複和合並Javascript數組的值

var recipients = [{ 
    name: 'Michael', 
    task: 'programming', 
    contactdetails: '[email protected]' 
}, { 
    name: 'Michael', 
    task: 'designing', 
    contactdetails: '[email protected]' 
}, { 
    name: 'Shane', 
    task: 'designing', 
    contactdetails: '[email protected]' 
}]; 

什麼我做的是一個排班系統,我發出通知,誰是這個星期,所以電子郵件就像「你好,邁克爾你在這周編程」。目前它不是很好,因爲它發送了一個電子郵件給數組中的每個值。所以在上面的例子中,它會發送Michael 2郵件。

我想要做的是在合併任務屬性字符串時刪除重複項。因此,陣列將是:

var recipients = [{ 
    name: 'Michael', 
    task: 'programming, designing', 
    contactdetails: '[email protected]' 
}, { 
    name: 'Shane', 
    task: 'designing', 
    contactdetails: '[email protected]' 
}]; 

這樣,它可以只發送一個消息,如「嗨邁克爾你是編程,這周的設計」。我如何去做這件事?我也在使用Google Apps腳本,因此我需要一個純JavaScript解決方案。我還應該補充說,每個人的姓名和電子郵件地址將永遠是相同的,所以邁克爾永遠不會有一個不同的電子郵件地址等您的幫助非常感謝!

+0

我們可以假設唯一的關鍵字是'contactdetails'字段嗎?或「contactdetails」和「name」字段? – haxxxton

+0

請勿將信息作爲評論添加,請將其置於問題中。另外,添加Google應用腳本標記。可能[* reduce *](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)將完成這項工作,你嘗試過了什麼? – RobG

+0

@haxxxton是的名字和contactdetails將永遠是相同的每個人,唯一的事情會改變一個人會在那裏的任務。 – user1190132

回答

3

這將是使用reduce函數的好機會。

我們所做的是循環遍歷每個原始收件人列表,看看我們是否已經處理過元素(如果有的話),將當前元素的任務追加到已處理的元素,否則將當前收件人添加到處理過的列表

// original array 
var recipients = [ 
    {name: 'Michael',task:'programming',contactdetails:'[email protected]'}, 
    {name: 'Michael',task:'designing',contactdetails:'[email protected]'}, 
    {name: 'Shane',task:'designing',contactdetails:'[email protected]'} 
]; 
var recipientKeyList = []; // used to store the contacts we've already processed 
// cycle through each recipient element 
var newRecipients = recipients.reduce(function(allRecipients, recipient){ 
    // get the indexOf our processed array for the current recipient 
    var index = recipientKeyList.indexOf(recipient.contactdetails); 
    // if the contact details already exist, append the task 
    if(index >= 0){ 
     allRecipients[index].task = allRecipients[index].task + ', ' + recipient.task; 
     return allRecipients 
    }else{ // otherwise append the recipient 
     recipientKeyList.push(recipient.contactdetails) 
     return allRecipients.concat(recipient); 
    } 

}, []); 
+0

已經有很多很棒的答案,我會花一些時間消化不同的選項,但是這個代碼很好。非常感謝您的幫助:) – user1190132

+1

是的,這與我所做的幾乎完全相同,只是我將它封裝在一個IIFE中以避免不必要的全局變量。 ;-) – RobG

+0

@RobG,人們會希望OP包含一段已經包裝在IIFE中的代碼片段;) – haxxxton

1
var recipients = [{name: 'Michael',task:'programming',contactdetails:'[email protected]'},{name: 'Michael',task:'designing',contactdetails:'[email protected]'},{name: 'Shane',task:'designing',contactdetails:'[email protected]'}]; 

var tempObj = {}; 
for (i=0; i<recipients.length; i++) { 
    if (!tempObj[recipients[i]['name']]) { 
     tempObj[recipients[i]['name']] = {}; 
     tempObj[recipients[i]['name']]['task'] = []; 
    } 
    tempObj[recipients[i]['name']]['task'].push(recipients[i]['task']); 
    tempObj[recipients[i]['name']]['contactdetails'] = recipients[i]['contactdetails']; 
} 

var new_arr = []; 
Object.keys(tempObj).forEach(function(key) { 
    new_arr.push({name: key, task: tempObj[key]['task'].join(", "), contactdetails: tempObj[key]['contactdetails']}) 
}); 
+0

你能解釋一下你在這段代碼中做了什麼? – Sikorski

+0

嗯,我遍歷數組,將它們按名稱排序並聚合任務名稱。 – kawadhiya21

+0

然後再次以「,」連接任務名稱,以數組格式排列它們。 – kawadhiya21

1

轉換陣列與鍵name對象(可以是電子郵件也)

// original array 
 
var recipients = [ 
 
    {name: 'Michael',task:'programming',contactdetails:'[email protected]'}, 
 
    {name: 'Michael',task:'designing',contactdetails:'[email protected]'}, 
 
    {name: 'Shane',task:'designing',contactdetails:'[email protected]'} 
 
]; 
 

 
var recipientsObj = {}; 
 
for (var i = 0; i < recipients.length; i++) { 
 
    var element = recipients[i]; 
 
    var recipientInObj = recipientsObj[element.name] 
 
    if (recipientInObj) { 
 
    // If a recipient is repeated with same task, here duplicates will appear 
 
    recipientInObj.task += ', ' + element.task; 
 
    } else { 
 
    recipientsObj[element.name] = element; 
 
    } 
 
} 
 
console.log(recipientsObj)

+0

創建一個數組只能立即加入它似乎是矯枉過正的沒有? – haxxxton

+0

添加了字符串連續替代 – Sangharsh

+0

'... + =','+ recipientsObj [element.name] .task;'鍵入的內容要少得多。 ;-) – RobG

1

迭代和尋找相同的對象,如果再附加任務,這樣

var recipients = [{ 
 
    name: 'Michael', 
 
    task: 'programming', 
 
    contactdetails: '[email protected]' 
 
}, { 
 
    name: 'Michael', 
 
    task: 'designing', 
 
    contactdetails: '[email protected]' 
 
}, { 
 
    name: 'Shane', 
 
    task: 'designing', 
 
    contactdetails: '[email protected]' 
 
}]; 
 

 

 
var uniqueR = []; 
 
var copyRecipients = JSON.parse(JSON.stringify(recipients)); 
 

 
copyRecipients .forEach(function(ele){ 
 
    var obj = uniqueR.find(function(e){ 
 
    return (e.name == ele.name && e.contactdetails == ele.contactdetails); 
 
    }); 
 
    if(obj){ 
 
    obj.task = obj.task + ", " + ele.task; 
 
    }else{ 
 
    uniqueR.push(ele); 
 
    } 
 
}); 
 

 
console.log(uniqueR)

+0

這會在*收件人*和* uniqueR *中的對象之間創建鏈接,這意味着您也要修改*收件人*(即* uniqueR *和*收件人*包含由該函數修改的完全相同的對象,請執行「控制檯.LOG(收件人)')。您可能需要將對象複製到其他答案中。 – RobG

+0

是的,gosh參考通過了同意 –

0

var newJSON = {}; (json.contactdetails)= {name:json [「name」],任務:newJSON [json.contactdetails]!= undefined & & newJSON [json.contactdetails ] [「task」]!= undefined?newJSON [json.contactdetails] [「task」] +「,」+ json [「task」]:json [「task」]}

});

+0

OP需要「一個純粹的JavaScript解決方案」 – haxxxton