我有一个带两个数组的函数。第一个数组称为字母,包括来自contacts数组的所有(唯一)起始字母。第二个参数采用前面提到的contacts数组。
该功能应根据其起始字母对所有联系人进行分组,并为每个字母和包含联系人创建一个新的数组和对象。该对象应如下所示:
{
"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
答案 0 :(得分: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);
&#13;
答案 1 :(得分: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;
}
或者您使用旧版本并改进逻辑(稍微慢一些),而且您也不需要字母:
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;
}
答案 2 :(得分:1)
我使用reduce
模式,因为它是为解决这些类型的问题而设计的。
Array.reduce
Array.sort
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);
&#13;
答案 3 :(得分:1)
您可以使用哈希表并收集字母数组。
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']));
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
答案 4 :(得分: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'])
&#13;