【问题标题】:Find completely unique names in an array在数组中查找完全唯一的名称
【发布时间】:2017-01-22 01:03:17
【问题描述】:

给定一个全名数组,其中每个名称的格式为“姓氏,名字”,我想找到完全唯一的名称,即给定下面的名称数组

const names = [
    'Smith, Joan',
    'Smith, John',
    'Smith, Sam',
    'Thomas, Joan',
    'Upton, Joan',
    'Upton, Tom',
    'Vasquez, Cesar'
  ]
- Smith, John # 已经看到姓氏“Smith” - Smith, Sam # 已经看到姓氏“Smith” - Thomas, Joan # 已经看到名字“Joan” - Upton, Joan # 已经看到名字“Joan” - Upton, Tom # 已经看到姓氏“Upton”

我只想拥有一个结果

 Smith, Joan
 Vasquez, Cesar

这是我目前拥有的功能。但是,我想重写它以避免嵌套的 for 循环并提高性能。

function findUnique() {
  const names = [
    'Smith, Joan',
    'Smith, John',
    'Smith, Sam',
    'Thomas, Joan',
    'Upton, Joan',
    'Upton, Tom',
    'Vasquez, Cesar'
  ];

  let result = names;
  for (var i = 0; i < names.length; i++) {
    for (var j = 1; j < names.length; j++) {
      let names1 = names[i].split(', ');
      let names2 = names[j].split(', ');
      if (names1[0] == names2[0] || names1[0] == names2[1] || names1[1] == names2[0] || names1[1] == names2[1]) {
        result.splice(i, 1);
      }
    }
  }

  return result;
}

【问题讨论】:

  • 根据您的描述和代码,Smith, Joan 不是唯一的,但是您说这是预期的结果,我很困惑。另外,for循环中的splice会改变索引。
  • 我已经添加了对什么被认为是“独特”的解释。基本上,如果名字或姓氏在名字中已经存在,则应该被拒绝
  • “George, Washington”和“Ian George”被认为是独特的还是不同的?
  • 那么正确的结果会根据名称的顺序而变化吗? (如果"Smith, Sam" 是数组中的第一个名字,它将在结果中而不是"Smith, Joan"

标签: javascript arrays


【解决方案1】:

使用 Set 对象。它是专门设计的,因此每个值中只能放入一个值。它有.has(value).add(value)方法

我还使用 for...of 循环来处理列表的迭代。

演示:https://jsfiddle.net/6tq00maq/1/

 const names = [
  'Smith, Joan',
  'Smith, John',
  'Smith, Sam',
  'Thomas, Joan',
  'Upton, Joan',
  'Upton, Tom',
  'Vasquez, Cesar'
]

//set up lists for first and last names
var firstNameList = new Set();
var lastNameList = new Set();

//set place for unique names to be stored
var uniqueNames = [];

//iterate list
for (var name of names) {
  var firstName = name.split(", ")[1];
  var lastName = name.split(", ")[0];

  //check if first name or last name are already indexed
  if (!firstNameList.has(firstName) && !lastNameList.has(lastName)) {
  //if not, push them to the unique names to return
    uniqueNames.push(lastName + ", " + firstName);
  }
  //add to indexed names
  firstNameList.add(firstName);
  lastNameList.add(lastName);
}
console.log(uniqueNames);

【讨论】:

    【解决方案2】:

    我会这样写:

    const names = [
      'Smith, Joan',
      'Smith, John',
      'Smith, Sam',
      'Thomas, Joan',
      'Upton, Joan',
      'Upton, Tom',
      'Vasquez, Cesar'
    ];
    
    const namesSeen = {};
    const uniqueNames = [];
    
    for (const name of names) {
      const [last, first] = name.split(", ");
    
      if (!namesSeen[first] && !namesSeen[last]) {
        uniqueNames.push(name);
      }
    
      namesSeen[first] = true;
      namesSeen[last] = true;
    }
    
    console.log(uniqueNames);
    

    我注意到您使用的是const,因此我使用了一些其他 ES6 特性来使代码感觉更自然:解构和 for...of 循环。

    【讨论】:

    • 好答案!一件事:你的变量 first 和 last 在你的析构中混淆了
    • @zfrisch 不错!
    【解决方案3】:

    记住我们见过的使用 JavaScript 对象哈希的名称。然后我们可以只运行一次数组:

    function findUnique() {
      const names = [
        'Smith, Joan',
        'Smith, John',
        'Smith, Sam',
        'Thomas, Joan',
        'Upton, Joan',
        'Upton, Tom',
        'Vasquez, Cesar'
      ];
      
      firstNames = {}; // First names we have already seen.
      lastNames = {};  // Last names we have already seen.
      result = [];
      
      for (var i = 0; i < names.length; i++) {
        let splitName = names[i].split(', ');
        let firstName = splitName[0];
        let lastName = splitName[1];
        
        // Check if we have seen either first name or last name.
        if (!(firstNames[firstName] || lastNames[lastName])) {
          // This is a "unique" name.
          result.push(names[i]);
        }
        
        // Add names to lists of names we have seen.
        firstNames[firstName] = true;
        lastNames[lastName] = true;
      }
       
      return result;
    }
    
    console.log(findUnique());

    【讨论】:

      【解决方案4】:

      使用filter 和单个Set 的解决方案。结果数组直接返回。仅当回调返回 true 时才会添加元素。

      const names = [
          'Smith, Joan',
          'Smith, John',
          'Smith, Sam',
          'Thomas, Joan',
          'Upton, Joan',
          'Upton, Tom',
          'Vasquez, Cesar'
      ];
      
      var n = new Set();
      
      var unique = names.filter(function(name) {
          var np = name.split(", ");
          if (n.has(np[0]) || n.has(np[1])) {
              return false;
          }
          n.add(np[0]).add(np[1]);
          return true;
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-27
        • 1970-01-01
        • 1970-01-01
        • 2022-10-13
        • 2014-02-09
        • 1970-01-01
        • 2015-12-08
        相关资源
        最近更新 更多