我有一系列的话:
["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;
}
因为你需要操纵数组和单个元素,我认为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);
我相信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"])));
如果您想要一个经典的递归解决方案,它可能如下所示:
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));
这是另一个赞美乔丹计划的经典递归定义。它是用表达式而不是语句编写的 -
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' ]
你可以使用reduce
这里的想法是
final
和temp
上初始化两个属性out
或of
我们将当前值添加到temp
out
或of
,我们在加入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)
如果你想要一个接近问题的解决方案,那么你可以简单地让reduce
返回一个由','
(例如"get_out_of,the,way"
)等字符分隔的字符串,然后split
返回由该字符产生的字符串:
let result = arr.reduce((a, b) =>
isPrepOrParticle(b)? a + "_" + b: a + "," + b
).split(",");
只需确保使用数组arr
中任何字符串未使用的字符。
注意:此解决方案要求arr
至少包含一个项目。您可以在执行上述代码之前先检查它。