JavaScript:如何处理所有后续元素对?

问题描述 投票:3回答:6

我有一系列的话:

["get", "out", "of", "the", "way"]

和功能:

isPrepOrParticle

对于元素“out”和“of”返回true。

我想用下划线将所有真实元素粘贴到以前的元素上并获得以下内容:

["get_out_of", "the", "way"]

通过对所有后续元组应用某种函数,是否有一种很好的功能方法:

f = (a, b) => {
  if (isPrepOrParticle(b)) return a + "_" + b;

  return null;
}
javascript lambda functional-programming reduce
6个回答
2
投票

因为你需要操纵数组和单个元素,我认为Array.reduce是你最好的选择。

var words = ["get", "out", "of", "the", "way"];
var special = ["out", "of"];

var janked = words.reduce((acc, el) => {
  if (special.includes(el) && acc.length) {
    // append underscore + current element to previous element
    acc[acc.length - 1] += "_" + el;
  } else {
    // just add this element to the array
    acc.push(el);
  }
  return acc;
}, []);

console.log(janked);

2
投票

我相信reduceRight也提供了一种以纯功能方式完成此任务的好方法:

const merge = (words, preps) =>
    words.reduceRight(([b, ...rest], a, i) => 
        preps.has(words[i+1]) ? [a+"_"+b, ...rest] : b ? [a, b, ...rest] : [a], []);

console.log(merge(["get", "out", "of", "the", "way"], new Set(["out", "of"])));

1
投票

如果您想要一个经典的递归解决方案,它可能如下所示:

const isPrepOrParticiple = word => word === 'out' || word === 'of';

function glue(a, b, ...rest) {
  if (a) {
    if (b) {
      if (isPrepOrParticiple(b)) {
        return glue(`${a}_${b}`, ...rest);
      }
      return [a, ...glue(b, ...rest)];
    }
    return [a];
  }
  return [];
}

const input = ['get', 'out', 'of', 'the', 'way'];

console.log(glue(...input));

1
投票

这是另一个赞美乔丹计划的经典递归定义。它是用表达式而不是语句编写的 -

const glue = (a = "", b = "", ...rest) =>
  b === ""                      // base: no b
    ? [ a ]
: a === ""                      // inductive: some b, no a
    ? []
: isPrepOrParticiple (b)        // inductive: some b, some a, participle
    ? glue (`${a}_${b}`, ...rest)
: [ a, ...glue (b, ...rest) ]   // inductive: some b, some a, non-participle

const isPrepOrParticiple = word =>
  word === 'out' || word === 'of'

console .log (glue ('get', 'out', 'of', 'the', 'way'))
// [ 'get_out_of', 'the', 'way' ]

0
投票

你可以使用reduce

这里的想法是

  • 首先,我们在对象finaltemp上初始化两个属性
  • 我们检查下一个索引,如果它是outof我们将当前值添加到temp
  • 一旦下一个指数不是outof,我们在加入temp之后将current value_添加到final中并再次将temp设置回空数组

let arr = ["get", "out", "of", "the", "way"]

let op = arr.reduce((op,inp,i)=>{
 if( arr[i+1] === 'out' || arr[i+1] === 'of' ){
  op.temp.push(inp)
 } else {
  op.final.push([...op.temp,inp].join('_'))
  op.temp = []
 }
 return op
},{final:[],temp:[]})

console.log(op.final)

0
投票

如果你想要一个接近问题的解决方案,那么你可以简单地让reduce返回一个由','(例如"get_out_of,the,way")等字符分隔的字符串,然后split返回由该字符产生的字符串:

let result = arr.reduce((a, b) =>
   isPrepOrParticle(b)? a + "_" + b: a + "," + b
).split(",");

只需确保使用数组arr中任何字符串未使用的字符。

注意:此解决方案要求arr至少包含一个项目。您可以在执行上述代码之前先检查它。

© www.soinside.com 2019 - 2024. All rights reserved.