![](/img/trans.png)
[英]JavaScript String.split(): Split by ; that is NOT preceded by a Backslash?
[英]JavaScript - String.split() but for Arrays?
假设我有这个字符串数组(它们是HTML元素,但是我们可以使用字符串来保持简单):
["something", "else", "and", "d", "more", "things", "in", "the", "d", "array", "etc"]
我需要一种快速的方法来用"d"
拆分该数组。 有点像String.split()
,除了数组。 最终结果应该是这样的:
[["something", "else", "and"], ["more", "things", "in", "the"], ["array", "etc"]]
有没有简单的一线工具呢? 也许JS中内置了一个函数,我只是想念它?
一种选择是用空格连接,然后用' d '
分割,然后用空格分割每个子数组:
const input = ["something", "else", "and", "d", "more", "things", "in", "the", "d", "array", "etc"]; const output = input .join(' ') .split(' d ') .map(str => str.split(' ')); console.log(output);
或者,不进行联接,就找出每个d
的索引,然后将输入的每个部分slice
d
s:
const input = ["something", "else", "and", "d", "more", "things", "in", "the", "d", "array", "etc"]; const dIndicies = input.reduce((a, item, i) => { if (item === 'd') a.push(i); return a; }, []); const output = dIndicies.reduce((a, dIndex, i, arr) => { const nextDIndex = arr[i + 1]; a.push(input.slice(dIndex + 1, nextDIndex)); return a; }, [input.slice(0, dIndicies[0] - 1)]); console.log(output);
好吧,如果您想要的是单线飞机,那么您就可以开始:
var myArray = ["something", "else", "and", "d", "more", "things", "in", "the", "d", "array", "etc"]; const result = myArray.reduce((a, c) => c === "d" ? (a.arr[++ai] = []) && a : a.arr[ai].push(c) && a, {arr: [[]], i: 0}).arr; console.log(result);
从具有一个包含空数组的数组的累加器开始使用reduce。 如果当前项目是拆分值,则在末尾添加一个额外的空数组,否则将当前项目散布到最后一个数组中。
const arr = ["something", "else", "and", "d", "more", "things", "in", "the", "d", "array", "etc"]; const splitArray = (array, val) => array && array.length ? array.reduce( (results, item) => item === val ? [...results, []] : [...results.filter((_, i) => i < results.length - 1), [...results[results.length - 1], item]], [[]] ) : array; console.log(splitArray(arr, 'd'));
let myArray = ["something", "else", "and", "d", "more", "things", "in", "the", "d", "array", "etc"]; let splitArray = [], tempArray = []; myArray.forEach((ele, index) => { if(ele !== 'd') { tempArray.push(ele); } if(ele === 'd' || index === myArray.length - 1) { splitArray.push(tempArray); tempArray = []; } }) console.log(': ', splitArray);
一个简单的forEach
方法就足够了。
var arr = ["something", "else", "and", "d", "more", "things", "in", "the", "d", "array", "etc"]; var result = [], temp = []; arr.forEach(function(elem, index){ elem !=='d' ? temp.push(elem) : (result.push(temp), temp = []); index==arr.length-1 && (result.push(temp)); }); console.log(result)
要回答您的问题,我不会想到任何简洁的单行代码,但是您可以通过迭代几行值以及如果单词不是'd'
存储它,只需用几行代码即可完成所需的操作; 如果是,则创建一个新数组来保存下一个非“ d”值:
const words = ["something", "else", "and", "d", "more", "things", "in", "the", "d", "array", "etc"] let grouped = words.reduce((response,word)=>{ if (word!=='d') response[response.length-1].push(word) else response[response.length]=[] return response },[[]]) console.log(grouped)
您可以使用以下类似的代码制作一个非常优雅的递归函数:
let arr = ["something", "else", "and", "d", "more", "things", "in", "the", "d", "array", "etc"] const spliton = (v, arr, i = arr.indexOf(v)) => (i < 0) ? [arr] : [arr.slice(0, i), ...spliton(v, arr.slice(i+1))] console.log(spliton('d', arr))
这是适用于任何可迭代输入(包括数组)的功能编码
const None = Symbol () const prepend = (xs, x) => [ x ] .concat (xs) const split = (f, [ x = None, ...xs ], then = prepend) => x === None ? then ([], []) : split ( f , xs , (l, r) => f (x) ? then (prepend (l, r), []) : then (l, prepend (r, x)) ) const data = [ 'something', 'else', 'and', 'd', 'more', 'things', 'in', 'the', 'd', 'array', 'etc' ] console .log ( split (x => x === 'd', data) ) // [ [ 'something', 'else', 'and' ] // , [ 'more', 'things', 'in', 'the' ] // , [ 'array', 'etc' ] // ]
优化适用于任何类似数组的输入
const prepend = (xs, x) =>
[ x ] .concat (xs)
const split = (f, xs = [], i = 0, then = prepend) =>
i >= xs.length
? then ([], [])
: split
( f
, xs
, i + 1
, (l, r) =>
f (xs[i])
? then (prepend (l, r), [])
: then (l, prepend (r, xs[i]))
)
const data =
[ 'something', 'else', 'and', 'd', 'more', 'things', 'in', 'the', 'd', 'array', 'etc' ]
console .log
( split (x => x === 'd', data)
)
// [ [ 'something', 'else', 'and' ]
// , [ 'more', 'things', 'in', 'the' ]
// , [ 'array', 'etc' ]
// ]
两种实现都是O(n) 。
如果您不关心更改数组,那么使用while
和Array.shift
也是很简单的:
let r = [[]], data = ["something", "else", "and", "d", "more", "things", "in", "the", "d", "array", "etc"] while(data.length) { let item = data.shift() item != 'd' ? r[r.length-1].push(item) : r.push([]) } console.log(r)
如果这样做,则使用Array.reduce
可以更短:
let arr = ["something", "else", "and", "d", "more", "things", "in", "the", "d", "array", "etc"] let f = arr.reduce((r,c) => (c!='d' ? r[r.length-1].push(c) : r.push([]),r),[[]]) console.log(f)
两者的想法都是从[[]]
,然后您唯一需要检查的是迭代的当前元素是否为d
,如果是,则推入新数组或推入r[r.length-1]
,即前一个sub array
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.