【问题标题】:Array spread values until matches length of another array length, to allow arrays to zip together数组传播值直到匹配另一个数组长度的长度,以允许数组压缩在一起
【发布时间】:2020-07-13 21:27:02
【问题描述】:

我有两个数组 ab
任何一个数组都可以有任意数量的项目。但是它们的长度可能不匹配。

我需要匹配数组长度,以便将两个数组压缩在一起。

例如:
a = [1, 2, 3, 4]b = [1, 2]

变成:
a = [1, 2, 3, 4]b = [1, 1, 2, 2]

我需要b 来匹配a 的长度,反之亦然,以匹配更长的长度。
以及传播较短数组的值,直到与较长数组的长度匹配。

较短数组上的展开将仅包含开始时存在的值。

例如: a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]b = [1, 2]

变成 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]b = [1, 1, 1, 1, 1, 2, 2, 2, 2, 2]

另一个例子:
a = [21, 22, 23, 24, 25, 26, 27]b = [39, 40, 41, 42]

变成:
a = [21, 22, 23, 24, 25, 26, 27]b = [39, 39, 40, 40, 41, 41, 42]

使用 Ramda 解决了它

const a = [1, 2] const b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

R.sort(R.gte, R.flatten(R.repeat(a, b.length / 2)))

【问题讨论】:

  • 扩展较短数组的逻辑是什么?如果较长的是 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 而较短的是 [1, 2] 会发生什么?
  • 你应该解释你想如何传播它们,但我几乎 100% 肯定你做了一些非常古怪的事情。
  • @VLAZ 我需要将两个数组压缩成对 [1, 2]。对于您的示例,它只是 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 和 [1, 1, 1, 1, 1, 2, ,2 ,2, 2, 2 ]
  • @VLAZ 谢谢你用 Ramda 解决了它 const a = [1, 2] const b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] R .sort(R.gte, R.flatten(R.repeat(a, b.length / 2)))

标签: javascript arrays list


【解决方案1】:

不依赖任何库,这个函数会给你想要的结果

const a = [21, 22, 23, 24, 25, 26, 27]
const b = [39, 40, 41, 42]

// a, b = longer array, shorter array
function spread(a, b) {
  let result = null
  if (a.length !== b.length) {
    // target: array that needs to be spread
    const [target, longest] = a.length > b.length ? [b, a] : [a, b]
    // difference: amount target needs to be spread
    const difference = longest.length - target.length
    // check if elements need to be repeated more than twice
    if (difference > target.length) {
      result = [].concat(
        ...target.map((n, i) => {
          if (typeof n !== 'string') {
            return Array.from(n.toString().repeat(difference / 2)).map(Number)
          }
          return Array.from(n.repeat(difference / 2))
        })
      )
    } else {
      // repeat N elements twice until N <= difference/2
      result = [].concat(
        ...target.map((n, i) => (i <= difference / 2 ? [n, n] : n))
      )
    }
    // return the spread array
    return result
  }
  // return original array if both arrays are same length
  return b
}

spread(a, b) // => [ 39, 39, 40, 40, 41, 42 ] 

【讨论】:

    【解决方案2】:

    纯 JavaScript 解决方案,它将较短的数组扩展到较长的数组的长度。拉伸是通过重复较短数组中的每个值并动态重新计算需要多少次来完成的。因此,长度为 10 和 3 时,较短的数组将第一项重复 3 次,但其余的仅重复两次以适应:

    longer length: 10
    
    shorter:   [ 1,       2, 3 ]
                /|\      /|  |\
               / | \    / |  | \
    result: [ 1, 1, 1, 2, 2, 3, 3 ]
    

    function equaliseLength(a, b) {
      const [shorter, longer] = [a, b].sort((x, y) => x.length - y.length);
    
      let remaining = longer.length;
      
      const stretchedArray = shorter.flatMap((item, index) => {
        //how many we need of this element
        const repeat = Math.ceil(remaining / (shorter.length - index));
        
        //adjust the remaining
        remaining -= repeat;
        
        //generate an array with the element repeated
        return Array(repeat).fill(item)
      });
      
      //return to the order of the input:
      //if `a` was the longer array, it goes first
      //otherwise flip them
      return longer === a ? 
        [longer, stretchedArray] :
        [stretchedArray, longer]
    }
    
    
    console.log(printResult(
      [1, 2, 3, 4], 
      [1, 2]
    ));
    console.log(printResult(
      [21, 22, 23, 24, 25, 26, 27], 
      [39, 40, 41, 42]
    ));
    console.log(printResult(
      [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 
      [1, 2]
    ));
    console.log(printResult(
      [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 
      [1, 2, 3]
    ));
    console.log(printResult(
      [1, 2, 3], 
      [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    ));
    
    console.log(printResult(
      [ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10],
      [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
    ));
    
    //just to make the display better
    function printResult(a, b) {
      const [resultA, resultB] = equaliseLength(a, b)
        .map(x => x.map(y => String(y).padStart(2)))
        .map(x => x.join("|"))
      
      return `a = ${JSON.stringify(a)} b = ${JSON.stringify(b)} 
    result:
    a = |${resultA}|
    b = |${resultB}|`;
    }

    【讨论】:

      猜你喜欢
      • 2019-04-07
      • 1970-01-01
      • 2022-11-19
      • 1970-01-01
      • 1970-01-01
      • 2018-08-04
      • 2018-02-22
      • 2023-03-23
      • 1970-01-01
      相关资源
      最近更新 更多