如何将一个数组中的缩写与另一个数组中的值匹配?

时间:2019-03-11 22:15:53

标签: javascript arrays

我有下面的代码,用于检查以确保数组1中至少有一个值出现在数组2中。

只要这样做,它将检查array2中是否存在任何首字母(长度为一个字符的值)。

如果存在,它将检查首字母是否匹配array1中任何值的首字母。

var array1 = ['Bob', 'Freddy', 'Johnson'];
var array2 = ['Bob', 'Johnson', 'F'];
var isValid = '';

if (array1.some(v => array2.includes(v)) == true) { //At least one value in array 1 appear in array 2
  if (anyInitials(array2) == 'yes') { // initials appear in array 2
    if (findName(array2, array1) == true) { //check initials in array 2 vs array 1
      isValid = 'yes';
    } else { //let's check the inverse, just in case
      isValid = 'no';
    }
  }
}
console.log('Do we match? = ' + isValid);

function findName(arr1, arr2) {
  for (let initial of arr1) {
    if (initial.length === 1) {
      return arr2.findIndex(name => name[0] === initial) != -1
    }
  }
}

function anyInitials(a) {
  var arrayLength = a.length;
  var isInitials = 'no';

  for (var i = 0; i < arrayLength; i++) {
    if (a[i].length == 1) {
      isInitials = 'yes';
    }
  }

  return isInitials;
}

一切正常,但是在一些更复杂的情况下,例如以下情况,我遇到了问题:

var array1 = ['Bob','Freddy', 'Johnson', 'Frank'];
var array2 = ['Bob', 'Johnson', 'Frank', 'F'];

如何确保针对array1中的“ Freddy”而不是“ Frank”对array2中的初始“ F”进行测试(因为两个数组中都存在Frank,因此应将其忽略)?

var array1 = ['Bob','Freddy', 'Johnson', 'Frank', 'Frederic'];
var array2 = ['Bob', 'Johnson', 'F', 'F'];

在上面的代码中,第一个“ F”应该针对“ Freddy”进行测试,第二个“ F”应当针对“ Frank”进行测试,因为Freddy已经匹配。但是,我们在“ Frederic”中有一个剩余部分,没有对应的匹配项(array2中没有名称),因此isValid应该说“ no”;

更复杂的情况:

var array1 = ['Bob','F', 'Freddy', 'Johnson', 'Frank'];
var array2 = ['Bob', 'J', 'F', 'Johnson', 'Freddy'];

“ J”找不到匹配项,因为“ Johnson”已经有一对。一个“ F”应自动与其配对,而另一个“ F”应针对其余的“ Frank”进行测试。这样就使“ Frank”无法对“ J”进行测试,后者应返回“ no”。

此时,与array2中的名字首对配对的数组1中的名字无关紧要。重要的是它是否可以配对。

每个数组都可以包含任意数量的值(每个值的最小值为1)。

谢谢

附录:到目前为止提出的解决方案将涉及从两个数组中删除所有匹配的名称,仅保留每个数组中不同的值。这仍然使我面临的问题是将名字的首字母匹配(经过修改的findName函数)。然后,需要从两个阵列中删除这些对,仅在每个阵列中保留其余部分(如果有)。如果array1中还有余数,则isValid会说“否”。

1 个答案:

答案 0 :(得分:1)

您不能真正一步完成,而是必须分两步进行。

  • 第一步是过滤所有一对一匹配的内容。
  • 此后,您必须确定自己的名字的全名或全名,然后进行匹配。

var names1 = ['Bob','Freddy', 'Johnson', 'Frank', 'Frederic'];
var names2 = ['Bob', 'Johnson', 'F', 'F', 'F'];
var names3 = ['Bob', 'Johnson', 'F', 'F', 'G'];
var names4 = ['Bob', 'Johnson', 'F', 'F'];

function test (array1, array2) {

  // If lenghts differ, then it fails
  if (array1.length !== array2.length) {
    return false
  }

  // copy arrays so you do not alter orginals
  var first = array1.slice()
  var second = array2.slice()

  // remove the exact matches
  array1.forEach( function (name, index) {
    var secondIndex = second.indexOf(name)
    if (secondIndex > -1) {
      first.splice(first.indexOf(name), 1)
      second.splice(secondIndex, 1)
    }
  })

  // if all matched, then we pass
  if (!first.length) {
    return true;
  }

  // now check to see if we have a abv match, 
  // every item in the array needs a match to pass
  return first.every(function (text) {
    var index = -1
    // if we have a full name, than match first
    if (text.length > 1) {
      var index = second.indexOf(text[0])
    } else {
      // we have an initial so need to first letter in full name
      var index = second.findIndex( function (secondText) {
        return text === secondText[0]
      })
    }
    // if we do not have a match then we have a failure
    if (index === -1) {
      return false
    } else {
      // when we have a match, remove it from the second so it can not be used again
      second.splice(index, 1)
      return true
    }
  })
}

console.log(1, test(names1, names1))
console.log(2, test(names1, names2))
console.log(3, test(names2, names1))
console.log(4, test(names1, names3))
console.log(5, test(names3, names1))
console.log(6, test(names1, names4))