2017-07-31 67 views
0

我有一個函數,需要兩個數組。第一個數組稱爲字母,幷包含來自聯繫人數組的所有(唯一)起始字母。第二個參數採用上述聯繫人數組。從聯繫人創建字母分組列表

函數應該根據它們的起始字母對所有聯繫人進行分組,併爲每個字母和包含聯繫人創建一個新的數組。對象應該看起來像這樣:

{ 
"letter": "S", 
"names": [Sample1, Sample2, Sample3] 
} 

該功能已經正常工作,但存在問題。如果有多個聯繫人具有相同的起始字母排列得到由上一接觸被覆蓋,所以最大的名字總是1.這是我與所有對象創建陣列功能:

function groupContacts(letters, contacts) { 
    var groupedContacts = []; 
    for (var i = 0; i < contacts.length; i++) { 
    for (var j = 0; j < letters.length; j++) { 
     if (
     letters[j].toLowerCase() === contacts[i].toLowerCase().substring(0, 1) 
    ) { 
     let names = [] 
     names.push(contacts[i]) 
     groupedContacts[j] = { 
      letter: letters[j], 
      name: names 
     }; 
     } 
    } 
    } 
    console.log(groupedContacts, "grouped Contacts"); 
} 

謝謝你的幫助!

PS:這裏的jsfiddle https://jsfiddle.net/bn7f8tsx

+1

請提供數據的小提琴。這裏 –

+0

https://jsfiddle.net/bn7f8tsx/是樣本數據的小提琴。由於 – zbkrt

+0

@zbkrt當有人請求的其他信息,請在你的問題更新,而不是將它張貼作爲替代.substring的'評論 – Rajesh

回答

3

你可以嘗試創建地圖的letters: names一個,然後遍歷這個地圖的鑰匙,並創建您的結構。

let contacts = ["Simon", "Mike", "Jake", "Lara", "Susi", "Blake", "James"]; 
 

 
var map = contacts.reduce((p, c) => { 
 
    let char = c.charAt(0).toUpperCase(); 
 
    p[char] = [].concat((p[char] || []), c) 
 
    return p; 
 
}, {}); 
 

 
var result = Object.keys(map).map(k => ({ 
 
    letter: k, 
 
    names: map[k] 
 
})); 
 

 
console.log(result);

+0

謝謝你這是一個很好的解決方案! – zbkrt

+0

偉大的解決方案,我也準備減少,但這是很多更有效 –

+1

@Jonasw首先,它不會爲O(n^2)你只有26個字符,如果我們的名稱都以全部字符,這將是26次多迭代。其次,「如果」條件也需要很長時間。第三,即使您的解決方案有2個循環,最終我想我們都將有反覆的同樣數量的 – Rajesh

1

你可以使用一個哈希表(所以你不需要搜索每次字母),這也犯規需要一個字母排列:

function groupContacts(contacts) { 
    var groupedContacts = [],hash={}; 
    contacts.forEach(function(contact){  
    var letter = contact.toLowerCase().substring(0, 1) 
    if(hash[letter]){ 
    hash[letter].names.push(contact); 
    }else{  
    groupedContacts.push(hash[letter]= { 
     letter, 
     names: [contact] 
    }); 
    } 
}); 
console.log(groupedContacts, "grouped Contacts"); 
return groupedContacts; 
} 

Try it

或者您使用舊版本並改進邏輯(稍慢),而且您也不需要在這裏使用字母:

function groupContacts(contacts) { 
var groupedContacts = []; 
contLoop:for (var i = 0; i < contacts.length; i++) { 
    for (var j = 0; j < groupedContacts.length; j++) { 
    if (
    groupedContacts[j].letter.toLowerCase() === 
    contacts[i].toLowerCase().substring(0, 1) 
    ) { 
    groupedContacts[i].names.push(contacts[i]); 
    continue contLoop;//exit is important 
    } 
    } 
    //no letter found, create new 
    groupedContacts[j] = { 
     letter: contacts[i].toLowerCase().substring(0, 1), 
     names:[contacts[i]] 
    }; 
} 
    console.log(groupedContacts, "grouped Contacts"); 
    return groupedContacts; 
} 

Try it

+0

(0,1)',你可以嘗試'的charAt(0)' – Rajesh

+0

@rajesh好耶點,但我認爲這不是一個關於表現的大問題。 –

0

所有你需要的是把你的let names = []串循環之外;

function groupContacts(letters, contacts) { 
 
    var groupedContacts = []; 
 
    let names = [] 
 
    for (var i = 0; i < contacts.length; i++) { 
 
    for (var j = 0; j < letters.length; j++) { 
 
     if (
 
     letters[j].toLowerCase() === contacts[i].toLowerCase().substring(0, 1) 
 
    ) { 
 
     
 
     names.push(contacts[i]) 
 
     groupedContacts[j] = { 
 
      letter: letters[j], 
 
      name: names 
 
     }; 
 
     } 
 
    } 
 
    } 
 
    console.log(groupedContacts, "grouped Contacts"); 
 
} 
 

 
groupContacts('S',['Sarah', 'John','Silvester', 'Tracy','Sean'])

+0

didt沒有爲我工作:) – zbkrt

1

我用reduce模式,因爲它是專爲解決這些類型的問題。

  1. 創建分組名單與Array.reduce
  2. 排序與Array.sort

Fiddle

let contacts = [ 
 
    "Simon", 
 
    "Mike", 
 
    "Jake", 
 
    "Lara", 
 
    "Susi", 
 
    "Blake", 
 
    "James" 
 
]; 
 

 
var contactsGrouped = contacts.reduce(function(contactList, name) { 
 
     var contactLetterGroup = contactList.filter(function(list) { 
 
      return list.letter == name[0].toUpperCase(); 
 
     }); 
 
     if (contactLetterGroup.length > 0) { 
 
      contactLetterGroup[0].name.push(name); 
 
     } else { 
 
      contactList.push({ 
 
       letter: name[0].toUpperCase(), 
 
       name: [name] 
 
      }); 
 
     } 
 
     return contactList; 
 
    }, []) 
 
    .sort(function(a, b) { 
 
     return b.letter - a.letter; 
 
    }) 
 

 
console.log(contactsGrouped);

+0

感謝時,這也能正常工作 – zbkrt

1

你可以使用一個哈希表和col選擇字母的數組。

function groupNames(array) { 
 
    var hash = Object.create(null), 
 
     result = []; 
 
     
 
    array.forEach(function (a) { 
 
     var k = a[0].toUpperCase(); 
 
     if (!hash[k]) { 
 
      hash[k] = []; 
 
      result.push({ letter: k, names: hash[k] }); 
 
     } 
 
     hash[k].push(a); 
 
    }); 
 
    return result; 
 
} 
 

 
console.log(groupNames(['Anne', 'Bert', 'Claudine', 'Dirk', 'Anton', 'Babette', 'Eugen', 'Felicitas']));
.as-console-wrapper { max-height: 100% !important; top: 0; }