首页 > 解决方案 > 函数从数组中返回项目,其中奇数索引处的项目由其前一个偶数索引处的数字重复

问题描述

面试某大公司的时候遇到了这个面试题。他们让我写出一个函数next,它将一个数组作为输入值并返回下一个可用的数字。

数组中偶数索引处的数字表示数组中奇数索引处下一个数字的编号。例如,[2,2,1,7,3,5]意味着我们有两个2s,一个7和 3 个5。因此调用next()2 2 7 5 5 5一次按顺序输出一个。并且当没有可用的数字时,在这种情况下,当5返回第三个时,该函数将抛出异常。

所以这个问题是非常开放的。他们没有明确指定我应该如何实现这个功能。唯一的要求是实现上述行为,即一次输出下一个可用的第一个。

在面试的时候我觉得把这个函数放在原型链上是有意义的,Array所以我们可以直接在这样的数组上调用这个函数

const array = [2, 2, 1, 7, 3, 5];

Array.prototype.next = function() {
  const buffer = [];
  let x;
  let index = 0;
  for (let i = 0; i < this.length; i++) {
    if (i % 2 === 0) {
      x = i;
    } else {
      buffer.push(...new Array(this[x]).fill(this[i]));
    }
  }
  return buffer[index++];
};

console.log(array.next()); // 2
console.log(array.next()); // 2
console.log(array.next()); // 2 

我注意到人们说将函数作为Array原型的一部分是个坏主意。所以这是另一个解决方案

function getNext(array) {
  const buffer = [];
  let x;
  let index = 0;
  for (let i = 0; i < array.length; i++) {
    if (i % 2 === 0) {
      x = i;
    } else {
      buffer.push(...new Array(array[x]).fill(array[i]));
    }
  }
  return buffer[index++];
}

然而问题是,它不记得最后一个输出并继续下一个输出。它将始终输出数组中的第一项。

我一直认为也许我们可以将其实现next为迭代器,但我自己无法实现。

有人可以帮我吗?

标签: javascriptecmascript-6frontend

解决方案


我认为自然适合这个问题的是生成器函数。您可以在此处阅读有关它们的更多信息: https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator

这是我的解决方案。如果您有任何问题,请告诉我:

const generatorFunc = function* (arr) {
  let i = 0;
  while (i < arr.length) {
    yield arr[i];
    i++;
  } 
};

const buildIterator = (arr) => {
  const generatedArr = arr.reduce((acc, item, itemIndex) => {
    const isEven = itemIndex % 2 === 0;
    if (isEven) {
      const value = arr[itemIndex + 1];
      const iterationCount = item;
      return acc.concat(Array(iterationCount).fill(value));
    };
    return acc;
  }, []);
  const generator = generatorFunc(generatedArr);
  return {
    next: () => {
      const nextIteration = generator.next();
      if (nextIteration.done) {
        throw new Error('No more items in array');
      }
      return nextIteration.value;
    }
  };
};

const myIterator = buildIterator([2,2,1,7,3,5]);

console.log(myIterator.next()); //2
console.log(myIterator.next()); //2
console.log(myIterator.next()); //7
console.log(myIterator.next()); //5
console.log(myIterator.next()); //5
console.log(myIterator.next()); //5
console.log(myIterator.next()); // ERROR!!

这里有一点语法糖,因为标准的 js 生成器函数返回像{ value, done }. 如果您有任何问题,请告诉我!


推荐阅读