“MapQuest”编码挑战 - 消除相互抵消的“方向”

Posted

技术标签:

【中文标题】“MapQuest”编码挑战 - 消除相互抵消的“方向”【英文标题】:"MapQuest" Coding Challenge - Eliminate "Directions" That Cancel Each Other Out 【发布时间】:2020-01-04 15:17:00 【问题描述】:

这个想法是消除在一系列方向上的无意义旅行:

'N' = 北

'S' = 南

'E' = 东

'W' = 西

因此,如果我们有数组 ['S', 'E', 'W', 'W'],我们希望 mapQuest 函数返回:

['S', 'W']

由于EastWest彼此相邻,因此它们会相互抵消。

*注意方向必须在数组中彼此相邻才能被抵消。

此外,数组应该继续减少,直到最终数组包含任何对立面 - 即它处理“复杂情况”:

['W', 'N', 'S', 'E', 'N']

应该返回

['N']

因为['W', 'N', 'S', 'E', 'N'] => ['W', 'E', 'N'] => ['N']

这个挑战的一部分是我必须使用reduce 方法。

根据我对.reduce()的理解,我的想法是:

function mapQuest (array) 
	return array.reduce((accumulator, current, i) => 
		if ((array[i] === 'S' && array[i + 1] !== 'N' && array[i - 1] !== 'N')) 
			accumulator.push(array[i]);
		

		if ((array[i] === 'N' && array[i + 1] !== 'S' && array[i - 1] !== 'S')) 
			accumulator.push(array[i]);
		
		
		if ((array[i] === 'E' && array[i + 1] !== 'W' && array[i - 1] !== 'W')) 
			accumulator.push(array[i]);
		

		if ((array[i] === 'W' && array[i + 1] !== 'E' && array[i - 1] !== 'E')) 
			accumulator.push(array[i]);
		
		
		return accumulator;
	, []);


console.log(mapQuest(['S', 'E', 'W', 'W']));

工作但没有通过最后的测试规范 - 处理复杂的情况。

期望['N', 'N', 'E', 'W', 'S', 'S', 'E', 'W', 'N', 'N', 'W', 'S', 'E'] 等于['N', 'N', 'W', 'S', 'E']

【问题讨论】:

检查未定义应该在检查元素之前。此外,match 用于匹配正则表达式。对于相等比较,您可以只使用current === 'S'。这样你也可以避免检查未定义。 @Slai - 在检查元素之前检查未定义会是什么样子?我试过if ((current !== undefined && current === 'S' && current[i + 1] !== 'N' || (current !== undefined && current === 'N' && current[i + 1] !== 'S'))) accumulator.push(current); 无需检查未定义。您只需要在 if 语句之后使用return accumulator;。否则,如果未返回任何内容,则该函数返回 undefined,并且 accumulator 对于下一个值变为 undefined。如果您不熟悉 reduce 的工作原理,我建议您先从基本的 for 循环开始。此外,您的 if 语句似乎并未处理所有情况。我认为您至少还需要两个。 @Slai 我现在要返回累加器,并且有 4 个不同的 if 语句应该考虑所有“相反方向的场景”。有些东西仍然无法正常工作...... 我认为你很接近。一些逻辑运算符是错误的,只有当 all 条件都满足时才应该推送值。 filter 应该比 reduce 更容易。 【参考方案1】:

一种解决方案,虽然不是很健壮,但是将缩减后的数组分配给一个变量,然后缩减该数组:

function mapQuest (array) 
	let first = array.reduce((accumulator, current, i) => 
		if ((array[i] === 'S' && array[i + 1] !== 'N' && array[i - 1] !== 'N')) 
			accumulator.push(array[i]);
		

		if ((array[i] === 'N' && array[i + 1] !== 'S' && array[i - 1] !== 'S')) 
			accumulator.push(array[i]);
		
		
		if ((array[i] === 'E' && array[i + 1] !== 'W' && array[i - 1] !== 'W')) 
			accumulator.push(array[i]);
		

		if ((array[i]=== 'W' && array[i + 1] !== 'E' && array[i - 1] !== 'E')) 
			accumulator.push(array[i]);
		
		
		return accumulator;
	, []);
	let second = first.reduce((final, current, index) => 
		if ((first[index] === 'S' && first[index + 1] !== 'N' && first[index - 1] !== 'N')) 
			final.push(first[index]);
		

		if ((first[index] === 'N' && first[index + 1] !== 'S' && first[index - 1] !== 'S')) 
			final.push(first[index]);
		
		
		if ((first[index] === 'E' && first[index + 1] !== 'W' && first[index - 1] !== 'W')) 
			final.push(first[index]);
		

		if ((first[index] === 'W' && first[index + 1] !== 'E' && first[index - 1] !== 'E')) 
			final.push(first[index]);
		
		
		return final;
	, []);
	return second;

console.log(mapQuest(['N', 'N', 'E', 'W', 'S', 'S', 'E', 'W', 'N', 'N', 'W', 'S', 'E']));

通过所有测试规范。

【讨论】:

【参考方案2】:

我为您提供此代码 sn-p 作为可能的答案。这是我所做的:

    我使用标准比较而不是match 我添加了额外的reduce 参数 我使用递归格式来确保最终答案发生缩减 我使用了一种非常规的方法来删除这些对,将它们标记为删除'X',然后将它们过滤掉

function mapQuest(quest, last) 

  if (JSON.stringify(quest) === JSON.stringify(last)) return quest;

  var initialQuest = quest.map(x => x);

  var newest = quest.reduce((accumulator, current, index, array) => 
    if ((current === 'S' && array[index + 1] === 'N') ||
      (current === 'N' && array[index + 1] === 'S')) 
      accumulator[index] = 'X';
      accumulator[index + 1] = 'X';
    
    if ((current === 'E' && array[index + 1] === 'W') ||
      (current === 'W' && array[index + 1] === 'E')) 
      accumulator[index] = 'X';
      accumulator[index + 1] = 'X';
    
    return accumulator;
  , initialQuest);

  var filtered = newest.filter(i => i !== 'X');

  return mapQuest(filtered, initialQuest);

var tests = [];
tests.push(
  input: ['S', 'E', 'W', 'W'],
  expected: ['S', 'W']
);
tests.push(
  input: ['W', 'N', 'S', 'E', 'N'],
  expected: ['N']
);
tests.push(
  input: ['N', 'N', 'E', 'W', 'S', 'S', 'E', 'W', 'N', 'N', 'W', 'S', 'E'],
  expected: ['N', 'N', 'W', 'S', 'E']
);

tests.forEach(test => 
  var output = mapQuest(test.input, []);
  var passed = JSON.stringify(test.expected) === JSON.stringify(output) ? 'passed' : 'failed';
  console.log(`$test.input => $output : $passed`);
);

【讨论】:

几乎拥有它。更新了代码以在比较和复制时处理数组引用问题。谢谢!

以上是关于“MapQuest”编码挑战 - 消除相互抵消的“方向”的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 中解析 mapquest 地理编码 JSON

从 python 列表中删除邮政编码(从 MapQuest 输出中获取州名)

为啥这个 CSS 中的元素相互抵消(在不涉及继承但带有注释的 HTML 中)彼此不相关?

WebRTC回声消除

再谈回声消除测评丨Dev for Dev 专栏

再谈回声消除测评丨Dev for Dev 专栏