【问题标题】:return "even" if others numbers are odd and "odd" the others number are even javascript如果其他数字是奇数,则返回“偶数”,而“奇数”其他数字是偶数 javascript
【发布时间】:2020-12-31 15:13:07
【问题描述】:

我有 2 个问题,如何在数组中获取值而不是值,以及如何使这段代码更短且具有声明性。

arr = [16, 4, 11, 20, 2]

arrP = [7, 4, 11, 3, 41]

arrTest = [2, 4, 0, 100, 4, 7, 2602, 36]

function findOutlier(arr) {
  const isPair = (num) => num % 2 === 0
  countEven = 0
  countOdd = 0
  arr1 = []
  arr2 = []
  const result = arr.filter((ele, i) => {
    if (isPair(ele)) {
      countEven++
      arr1.push(ele)

    } else {
      countOdd++

      arr2.push(ele)
    }

  })
  return countEven > countOdd ? arr2 : arr1

}

console.log(findOutlier(arrTest))

【问题讨论】:

  • 你能澄清你想要做什么吗?我很难理解你在寻找什么结果。
  • 您是否尝试将数组拆分为even 数组和odd 数组,然后返回较长的数组?
  • 三元不是倒过来的吗?预期的输出是什么?
  • 当奇数和偶数都不是一个时,函数应该返回什么,例如 [1, 3, 2, 4, 6]?标题似乎还要求输出字符串(“偶数”、“奇数”),但这不是您的代码正在做的事情……您能澄清一下吗?
  • 是否只有一个元素与其他元素不同?

标签: javascript arrays outliers declarative


【解决方案1】:

过滤两次可能更具可读性。

even = arr.filter((x) => x % 2 == 0);
odd = arr.filter((x) => x % 2 == 1);
if (even.length > odd.length) {
    return even;
} else {
    return odd;
}

【讨论】:

    【解决方案2】:

    如果您希望使用一个循环来执行此操作,请考虑使用数组 reduce 方法将每个数字放入偶数或奇数桶中,然后在返回时比较这些桶的长度:

    function findOutlier(arr) {
      const sorted = arr.reduce((acc, el) => {
        acc[el % 2].push(el);
        return acc;
      },{ 0: [], 1: [] })
      
      return sorted[0].length > sorted[1].length ? sorted[1] : sorted[0];
    }
    
    const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    
    console.log(findOutlier(arr));

    请注意,当数组正常长度相同时,这不会处理(现在它只会返回奇数数组)。

    【讨论】:

    • 你为什么要把它存入数组,你可以创建一个像{0: 0, 1: 0}这样的数字,然后将它加1。它会消耗更少的内存。
    • @RinkeshGolwala 因为看似 OP 不仅需要奇数/偶数,还需要值...
    • 是的,OP 想要中奖数组(全是偶数或全是奇数)。
    • 好的,知道了。谢谢
    • 嗯,实际上似乎 OP 想要 shorter 数组,所以我为此调整了我的代码。
    【解决方案3】:

    如果其中一种类型的计数为 1,而其他类型的计数大于 1,则您可以取出带有所需部件的对象进行收集并添加短路。

    const
        isPair = num => num % 2 === 0,
        findOutlier = array => {
            count = { true: [], false: [] };
            for (const value of array) {
                count[isPair(value)].push(value);
                if (count.true.length === 1 && count.false.length > 1) return count.true[0];
                if (count.false.length === 1 && count.true.length > 1) return count.false[0];
            }
        };
    
    console.log(...[[16, 4, 11, 20, 2], [7, 4, 11, 3, 41], [2, 4, 0, 100, 4, 7, 2602, 36]].map(findOutlier));

    【讨论】:

      【解决方案4】:

      这是一个根据取模结果选择evenodd 数组的解决方案。

      function findOutlier(integers) {
        const even = [], odd = [], modulos = [even, odd];
        for (const integer of integers) {
          modulos[Math.abs(integer % 2)].push(integer);
        }
        return even.length > odd.length ? odd : even;
      }
      
      console.log(findOutlier([2, 4, 0, 100, 4, 7, 2602, 36]));

      不幸的是,您确实需要Math.abs() 来处理负值,因为-3 % 2 == -1

      见:JavaScript % (modulo) gives a negative result for negative numbers

      但是findOutlier 这个名字让我假设在提供的列表中只有一个异常值。如果是这种情况,您可以优化算法。

      function findOutlier(integers) {
        // With less than 3 integers there can be no outlier.
        if (integers.length < 3) return;
        
        const isEven = (integer) => integer % 2 == 0;
        const isOdd  = (integer) => !isEven(integer);
        
        // Determine the outlire based on the first 3 elements.
        // If there are 0 or 1 integers even, the outlire is even.
        // if there are 2 or 3 integers even, the outlier is odd.
        const outlier = integers.slice(0, 3).filter(isEven).length < 2
                      ? isEven
                      : isOdd;
      
        return integers.find(outlier);
      }
      
      console.log(findOutlier([2, 4, 0, 100, 4, 7, 2602, 36]));

      【讨论】:

        【解决方案5】:

        您可以在不创建中间数组的情况下执行此操作,只需将每个元素与其相邻元素进行比较,如果两者都不同则返回该元素,如果未找到异常值则返回未定义元素。这将在首次遇到异常值的同一迭代中返回,并返回值本身而不是数组。

        function findOutlier(array) {
          const
            len = array.length,
            isEven = (n) => n % 2 === 0;
        
          for (const [i, value] of array.entries()) {
            let
              prev = array[(i-1+len)%len], // loop around if < 0 (first element)
              next = array[(i+1)%len];     // loop around if >= length (last element)
            if (isEven(value) !== isEven(prev) && isEven(value) !== isEven(next)) {
              return value;
            }
          }
          return undefined;
        }
        
        const arrays = [[16, 4, 11, 20, 2], [7, 4, 11, 3, 41], [2, 4, 0, 100, 4, 7, 2602, 36]]
        console.log(...arrays.map(findOutlier));

        【讨论】:

          【解决方案6】:

          既然 OP 澄清了要求(至少在评论中),这允许使用不同的方法:

          function findOutlier(array) {
            let odd = undefined, even = undefined;
          
            for (let i of array) {
              let isEven = i % 2 == 0;
            
              if (odd !== undefined && even !== undefined)
                return isEven ? odd : even;
          
              if (isEven) even = i;
                else odd = i;
            }
            
            if (odd !== undefined && even !== undefined)
              return array[array.length-1];
          }
              
              
          console.log(findOutlier([2,4,6,8,10,5]))

          算法将迭代数组,并分别存储最新发现的奇数和偶数。

          如果我们已经发现了一个奇数和一个偶数,我们可以根据当前的数字来判断,其中哪个是异常值:如果当前数字是偶数,它至少是我们找到的第二个偶数。因此,找到的奇数必须是异常值。如果当前数字是奇数,反之亦然。特殊情况,如果异常值是数组的最后一个元素,则在循环之后使用附加条件进行检查。

          如果所有数字都是奇数或偶数(即没有异常值),此函数将返回 undefined。如果不满足前提条件,即存在多个异常值,该算法不会抛出错误。

          【讨论】:

            猜你喜欢
            • 2013-12-11
            • 1970-01-01
            • 2015-05-31
            • 2011-11-12
            • 1970-01-01
            • 2016-04-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多