代码之家  ›  专栏  ›  技术社区  ›  DNorthrup

使用Ramda“range”进行复制,但需要每隔3次插入(React)

  •  0
  • DNorthrup  · 技术社区  · 7 年前

    我目前正在使用Ramda输出 Material-UI CheckCircle 对于 perk 有一个记录。他们最多可以有18个,所以我也用它来计数 past the perk 最大为 18 显示潜在最大值。

    {R.range(0, this.props.perkProgress).map(() => <CheckCircle key={uid()} /> )}
                {R.range(this.props.perkProgress, 18).map(() => <CheckBoxOutline key={uid()} /> )}
    

    这两行很好地工作,但是我还需要在每一个“第三行”后面插入一些内容-更确切地说,这是一个方框或复选标记。既然我不相信我可以使用Ramda,那么我如何以正常的JS方式编写它(或者将其包装在函数中;任意一个)来获得所需的输出呢?

    this.props.perkProgress 始终是介于0和18之间的整数。

    如果他们有“5”,我预计会有5个复选标记和13个空方块。

    添加 terrible drawing 当前运行的部分,以及所需的最终结果:

    enter image description here

    1 回复  |  直到 7 年前
        1
  •  2
  •   Scott Christopher    7 年前

    这可以通过使用Ramda来实现,首先使用 R.splitEvery 然后使用在每个拆分列表之间添加分隔符 R.intersperse 并最终将拆分列表与 R.unnest .

    (注意,为了简洁起见,我用下面的字符串替换了JSX)

    // inserts `sep` between every `n` elements of a list `xs`
    const separateEvery = (sep, n, xs) =>
      R.unnest(R.intersperse([sep], R.splitEvery(n, xs)))
    
    const genElements = (totalSize, progress) =>
      separateEvery('Separator', 3, R.concat(
        R.repeat('CheckCircle', progress),
        R.repeat('CheckBoxOutline', totalSize - progress)
      ))
    
    console.log(genElements(18, 7))
    <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

    针对以下评论的更新


    向每个生成的元素添加键的一种方法是使用 React.cloneElement .

    const genElementsWithKey = R.pipe(
      genElements,
      R.addIndex(R.map)((el, key) => React.cloneElement(el, {key}))
    )
    

    或者,如果您不想使用 cloneElement 因为某种原因你可以换掉 R、 散布 使用 R.zipWith 创建要在每组元素之间插入的唯一分隔符元素。

    const createCircle = _ => '<CheckCircle key={uid()} />'
    const createCheckBox = _ => '<CheckBoxOutline key={uid()} />'
    const createSeparator = _ => '<Separator key={uid()} />'
    
    const genElements = (totalSize, progress) => {
      const splitEls = R.splitEvery(3, R.concat(
        R.map(createCircle, R.range(0, progress)),
        R.map(createCheckBox, R.range(progress, totalSize))
      ))
      
      const firstSplitGroup = splitEls[0]
      const remainingSplitGroups = R.tail(splitEls)
      
      // create a list of separators matching the number of elements in remainingSplitGroups
      const separators = R.map(createSeparator, R.range(0, remainingSplitGroups.length))
      
      return R.concat(
        // keep the first split group as is
        firstSplitGroup,
        // prepend a separator to each of the remaining split groups
        R.unnest(R.zipWith(R.prepend, separators, remainingSplitGroups))
      )
    }
    
    console.log(genElements(18, 7))
    <script src=“//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js”></脚本(>);