简体   繁体   English

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

[英]JavaScript - String.split() but for Arrays?

Let's say I have this array of strings (they're HTML elements, but we can use strings to keep it simple): 假设我有这个字符串数组(它们是HTML元素,但是我们可以使用字符串来保持简单):

["something", "else", "and", "d", "more", "things", "in", "the", "d", "array", "etc"]

I need a quick way to split this array up by "d" . 我需要一种快速的方法来用"d"拆分该数组。 Kinda like String.split() , except for arrays. 有点像String.split() ,除了数组。 The end result should be something like this: 最终结果应该是这样的:

[["something", "else", "and"], ["more", "things", "in", "the"], ["array", "etc"]]

Are there any simple one-liners for this? 有没有简单的一线工具呢? Maybe there's a function built into JS and I'm just missing it? 也许JS中内置了一个函数,我只是想念它?

One option would be to join by spaces, then split by ' d ' , then split each subarray by spaces: 一种选择是用空格连接,然后用' 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); 

Or, without joining, figure out the index of every d , and slice every section of the input around the d s: 或者,不进行联接,就找出每个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); 

Well if it's a one-liner you want, here you go: 好吧,如果您想要的是单线飞机,那么您就可以开始:

 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); 

Use reduce starting with an accumulator that has an array containing an empty array. 从具有一个包含空数组的数组的累加器开始使用reduce。 If the current item is the split value add an extra empty array to the end, otherwise spread the last array with the current item. 如果当前项目是拆分值,则在末尾添加一个额外的空数组,否则将当前项目散布到最后一个数组中。

 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); 

A simple forEach approach is enough. 一个简单的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) 

To answer your question, there aren't any concise one-liners that come to mind, but you may accomplish what you want with just a few lines of code by iterating over your values and if the word isn't 'd' store it; 要回答您的问题,我不会想到任何简洁的单行代码,但是您可以通过迭代几行值以及如果单词不是'd'存储它,只需用几行代码即可完成所需的操作; if it is, then create a new array to hold the next non-'d' value: 如果是,则创建一个新数组来保存下一个非“ 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) 

You can make a pretty elegant recursive function with something like: 您可以使用以下类似的代码制作一个非常优雅的递归函数:

 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)) 

Here's a functional encoding that works for any iterable input (including arrays) 这是适用于任何可迭代输入(包括数组)的功能编码

 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' ] // ] 

And an optimization that works for any array-like input 优化适用于任何类似数组的输入

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' ]
// ]

Both implementations are O(n) . 两种实现都是O(n)

If you do not care about mutating the array this is also pretty trivial with while and Array.shift : 如果您不关心更改数组,那么使用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) 

And if you do then even shorter with Array.reduce : 如果这样做,则使用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) 

The idea in both is to start with [[]] and then the only check you need is if the current element of the iteration is d and if so push new array or push to r[r.length-1] which is the previous sub array . 两者的想法都是从[[]] ,然后您唯一需要检查的是迭代的当前元素是否为d ,如果是,则推入新数组或推入r[r.length-1] ,即前一个sub array

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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