我有一个字符串数组,类似于这样:
["x", "foo", "y", "bar", "baz", "z", "0"]
我需要将数组根据X、Y和Z或其他特殊关键词进行拆分。
我尝试使用[x,y,z].split(y)
来拆分数组,但我很确定split()
只适用于字符串。
这些关键词(x、y和z)必须是数组中的第一个。
我应该怎么做呢?以下是我想要的结果:
[
["x", "foo"],
["y", "bar", "baz"],
["z", "0"]
]
我有一个字符串数组,类似于这样:
["x", "foo", "y", "bar", "baz", "z", "0"]
我需要将数组根据X、Y和Z或其他特殊关键词进行拆分。
我尝试使用[x,y,z].split(y)
来拆分数组,但我很确定split()
只适用于字符串。
这些关键词(x、y和z)必须是数组中的第一个。
我应该怎么做呢?以下是我想要的结果:
[
["x", "foo"],
["y", "bar", "baz"],
["z", "0"]
]
您可以使用数组和闭包来对索引键字符串进行操作,如果找到一个键,则将空数组推入其中。
var array = ["x", "foo", "y", "bar", "baz", "z", "0"],
keys = ["x", "y", "z"],
result = array.reduce((i => (r, s) => {
if (s === keys[i]) {
r.push([]);
i++;
}
r[r.length - 1].push(s);
return r;
})(0), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
keys
按顺序出现,对吗?即使需要,闭包也会让人困惑。要么将变量i
放在外部范围,要么如果你喜欢函数式编程,就在累加器中将其穿透传递。 - Bergiconcat(result) == input
成立。 - Bergi const keywords = new Set(["x", "y", "z"]);
let acc = [];
const result = [];
for(const el of array) {
if(keywords.has(el)) {
result.push(acc = [el]);
} else acc.push(el);
}
我来晚了,但我将展示与其他答案完全不同的方法。在此方法中,使用join()
将输入数组转换为字符串,并使用主要使用正则表达式和split()
方法获取结果:
const input = ["x", "foo", "y", "bar", "baz", "z", "0"];
const keyRegex = /(?=#x#)|(?=#y#)|(?=#z#)/;
let res = ("#" + input.join("#") + "#") // #x#foo#y#bar#baz#z#0#"
.split(keyRegex) // [#x#foo, #y#bar#baz, #z#0#]
.map(str => str.split("#").filter(Boolean));
console.log(JSON.stringify(res));
这里有另一种使用 map()
方法的方法来遍历带有 keys
的数组。请注意,我已将 input
数组的副本传递给了 map
方法,并将其用作 this
参数。此外,我在 this
上使用 splice()
来删除已经分析过的部分,并对缩短后的数组执行未来的 findIndex()
。然而,这些都比不上使用 reduce()
或标准的 loop
遍历输入数组的解决方案。
const input = ["x", "foo", "y", "bar", "baz", "z", "0"];
const keys = ["x", "y", "z"];
let res = keys.map(function(k, i)
{
let a = this.findIndex(x => x === k);
let b = this.findIndex(x => x === keys[i+1]);
return this.splice(a, b >= 0 ? b : this.length);
}, input.slice());
console.log(JSON.stringify(res));
另一种方法是使用slice
函数:
最初的回答。
var a = ["x", "foo", "y", "bar", "baz", "z", "0"];
var breakpoints = ['x', 'y', 'z'];
var res = [];
for(var i = 0; i < breakpoints.length - 1; i++) {
res = res.concat([a.slice(a.indexOf(breakpoints[i]), a.indexOf(breakpoints[i+1]))]);
}
res = res.concat([a.slice(a.indexOf(breakpoints[i]))]);
console.log(res);
这是对已经发布的好答案的简短替代方案,如果有帮助的话。
这是使用 Array.reduce
实现的:
const input = ['x', 'foo', 'y', 'bar', 'baz', 'z', '0'];
const keywords = ['x', 'y', 'z'];
const result = input.reduce((result, value) => {
keywords.includes(value) ? result.push([value]) : result[result.length - 1].push(value);
return result;
}, []);
console.log(result);
keywords.includes(value) || keywords.length === 0
。在第一阶段使用双重减少,计算每个键的索引,在第二次减少中拆分数组:
var arr = ["x", "foo", "y", "bar", "baz", "z", "0"];
var keys = keys = ["x", "y", "z"];
var retVal = arr.reduce(function(acc, ele, idx) {
if (keys.indexOf(ele) > -1) {
acc.push(idx);
}
return acc;
}, []).reduce(function(acc, ele, idx, a) {
acc.push(arr.slice(ele, a[idx+1]));
return acc;
}, []);
console.log(retVal);
slice
按给定键的索引提取单个数组并将其推入最终数组中。
const arr = ["x", "foo", "y", "bar", "baz", "z", "0"];
function splitByKeys(...keys){
let splitarr = [];
for(let i =0; i<keys.length;i++){
if(i == keys.length -1 ){
splitarr.push(arr.slice( arr.indexOf(keys[i]) , arr.length));
}else{
splitarr.push(arr.slice( arr.indexOf(keys[i]) , arr.indexOf(keys[i+1])));
}
}
return splitarr;
}
console.log(splitByKeys("x", "y", "z"));
Pretty simple!
const arr = ["x", "foo", "y", "bar", "baz", "z", "0"];
const specialChar = ['x', 'y', 'z'];
let result = [];
arr.forEach((el, index) => {
if(specialChar.includes(el)){
result.push([el, arr[index + 1]])
}
});
console.log(result)
function separator(a) {
var result = [];
for (var i = 0; i < a.length; i++) {
var index = a[i].trim().toLowerCase();
switch (index) {
case "x":
case "y":
case "z":
if (result[index] == undefined) {
result.push([index]);
}
break;
default:
result[result.length - 1].push(a[i]);
}
}
return result;
}
// Sample:
var arr = ["x", "foo", "y", "bar", "baz", "z", "0"];
console.log(separator(arr));
// Result must be:
// [["x", "foo"], ["y", "bar", "baz"], ["z", "0"]]
或者使用这个来进行分组:
function separator(a) {
var result = {};
var lastIndex = "";
for (var i = 0; i < a.length; i++) {
var index = a[i].trim().toLowerCase();
switch (index) {
case "x":
case "y":
case "z":
if (result[index] == undefined) {
result[index] = [];
}
lastIndex = index;
break;
default:
result[lastIndex].push(a[i]);
}
}
return result;
}
// Sample:
var arr = ["x", "foo", "y", "bar", "baz", "z", "0"];
console.log(separator(arr));
// Result must be:
// {"x": ["foo"], "y": ["bar", "baz"], "z": ["0"]}
["x", "foo", "y", "bar", "x", "baz", "z", "0", "y", "bar2"]
And result is this:
{"x": ["foo", "baz"], "y": ["bar", "bar2"], "z": ["0"]}
const input = ['x', 'foo', 'y', 'bar', 'baz', 'z', '0'];
const keywords = ['x', 'y', 'z'];
input.reduce((prev, val) => {
const split = keywords.includes(val);
const index = prev.length - Number(!split);
prev[index] = split ? [val] : prev[index].concat(val)
return prev;
}, []);