6

在网上看到这个白板挑战,似乎无法弄清楚。帮助!

创建一个接受单词数组作为输入的函数。

您的函数应该返回一个所有单词的数组,这些单词可以使用只能在标准美式 QWERTY 键盘的单行上访问的字母表中的字母键入。

例如:

// given
let words = [ 'sup', 'dad', 'tree', 'snake', 'pet'];
keyboardWords(words);

// return
['dad', 'tree', 'pet'];

这就是我已经走了多远。

const topKeys = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'];
const middleKeys = ['a', 's', 'd','f', 'g', 'h', 'j', 'k', 'l'];
const buttomKeys = ['z', 'x', 'c', 'v', 'b', 'n', 'm'];

let result = [];

let words = ['sup', 'dad', 'tree', 'snake', 'pet'];

for(let i in words) {
  let eachWord = words[i];

  eachWord.split('').forEach(function(c) {
    console.log(c);
  });

}

我已经到了要打印数组中的每个单词的地步,但不完全知道使用什么方法来查看单个数组中单词中的每个字母是否是 topKeys、middle Keys 等...

4

4 回答 4

2

有关详细信息,请参阅Array.prototype.filter()SetSpread SyntaxString.prototype.toLowerCase()Array.prototype.every()

// Input.
const input = [
  'ERUT', // top match
  'wdvrmg', // false
  'dsjf', // middle match
  '!^#@&^#', // false
  'CxmvN', // bottom match
  '53454', // false
  '' // false
]

// Match.
const match = (A, B) => [...A].every(x => B.has(x.toLowerCase()))

// Line Words.
const lineWords = words => words.filter(word => word.length && (
  
  // Top match.
  match(word, new Set(['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'])) ||
  
  // Middle match.
  match(word, new Set(['a', 's', 'd','f', 'g', 'h', 'j', 'k', 'l'])) ||
  
  // Bottom match.
  match(word, new Set(['z', 'x', 'c', 'v', 'b', 'n', 'm']))
  
))

// Output.
const output = lineWords(input)

// Proof.
console.log(output)

于 2018-04-11T01:19:43.430 回答
1

显然有很多方法可以做到这一点。我最初的反应是制作一个哈希表。我不确定它是否比其他任何一个都好,但它应该执行合理并且易于理解/在白板上书写:

const rows = [
  ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'],
  ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'],
  ['z', 'x', 'c', 'v', 'b', 'n', 'm']
];

// make a quick hash
const hash = rows.reduce((acc, row, i) => (row.forEach(letter => acc[letter] = i + 1), acc), {})
let words = ['sup', 'dad', 'tree', 'snake', 'pet', "4545", "", "PoWer", '0'];

let result = []

words.forEach(word => {
  if (!word) return                     // degenerate cases i.e  '', 0, etc.
  let row = hash[word[0].toLowerCase()]
  if (row == undefined) return          // not letters we know about
  for (let i = 1; i < word.length; i++) {
    if (hash[word[i].toLowerCase()] !== row) return
  }
  result.push(word)
})

console.log(result)

于 2018-04-11T02:17:08.143 回答
0

您可以处理它的多种方法之一:

const topKeys = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'];
const middleKeys = ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'];
const bottomKeys = ['z', 'x', 'c', 'v', 'b', 'n', 'm'];

const keysets = [topKeys, middleKeys, bottomKeys];

function fn(words) {
	let result = [];

	for (let j = 0; j < words.length; j++) {
		let word = words[j];
		keysets.forEach(function (keyset) {
			if (test(word, keyset)) {
				result.push(word);
			}
		});
	}

	function test(word, keyset) {
		let ok = false;
		for (let i = 0; i < word.length; i++) {
			let char = word.charAt(i);
			ok = keyset.indexOf(char) > -1;
			if (!ok) {
				break;
			}
		}

		return ok;
	}

	return result;
}

let words = ['sup', 'dad', 'tree', 'snake', 'pet'];

let result = fn(words);

console.log(result);

于 2018-04-11T00:38:15.557 回答
0

您可能应该使用.filter来检查数组的哪些元素通过了特定的测试。然后使用every查看哪些单词通过:

const keyboardWords = (() => {
  const topKeys = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'];
  const middleKeys = ['a', 's', 'd','f', 'g', 'h', 'j', 'k', 'l'];
  const bottomKeys = ['z', 'x', 'c', 'v', 'b', 'n', 'm'];
  return (words) => {
    return words.filter((word) => {
      const chars = word.split('');
      return chars.every(char => topKeys.includes(char))
        || chars.every(char => middleKeys.includes(char))
        || chars.every(char => bottomKeys.includes(char))
    });
  };
})();

const input = [ 'sup', 'dad', 'tree', 'snake', 'pet'];
console.log(keyboardWords(input))

于 2018-04-11T00:13:20.907 回答