繁体   English   中英

JavaScript-String.split()但用于数组吗?

[英]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)

如果您不关心更改数组,那么使用whileArray.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM