从联系人创建字母分组列表

时间:2017-07-31 10:26:02

标签: javascript arrays

我有一个带两个数组的函数。第一个数组称为字母,包括来自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

5 个答案:

答案 0 :(得分:3)

您可以尝试创建letters: names的地图,然后循环显示此地图的键并创建您的结构。

&#13;
&#13;
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;
&#13;
&#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;
}

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

答案 2 :(得分:1)

我使用reduce模式,因为它是为解决这些类型的问题而设计的。

  1. 使用Array.reduce
  2. 创建了一个分组列表
  3. Array.sort
  4. 排序

    Fiddle

    &#13;
    &#13;
    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;
    &#13;
    &#13;

答案 3 :(得分:1)

您可以使用哈希表并收集字母数组。

&#13;
&#13;
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;
&#13;
&#13;

答案 4 :(得分:0)

您只需将let names = []字符串放在循环之外;

&#13;
&#13;
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;
&#13;
&#13;