在数组中查找完全唯一的名称

时间:2017-01-22 01:03:17

标签: javascript arrays

给定一个全名数组,其中每个名称的格式为' lastName,firstName',我想找到完全唯一的名称,即给出下面的名称数组

const names = [
    'Smith, Joan',
    'Smith, John',
    'Smith, Sam',
    'Thomas, Joan',
    'Upton, Joan',
    'Upton, Tom',
    'Vasquez, Cesar'
  ]
- Smith, John     # Already saw a last name "Smith"
- Smith, Sam      # Already saw a last name "Smith"
- Thomas, Joan    # Already saw a first name "Joan"
- Upton, Joan     # Already saw a first name "Joan"
- Upton, Tom      # Already saw a last name "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;
}

4 个答案:

答案 0 :(得分:3)

使用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);

答案 1 :(得分:1)

这就是我写它的方式:

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功能来让代码感觉更自然:解构和循环。

答案 2 :(得分:0)

记住我们使用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());

答案 3 :(得分:0)

使用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;
});