0

i want to split an array into a list of subarray by a/or more given seperator/s.

something like this:

var myArray = [null, 5, 'whazzup?', object, '15', 34.6];
var mySeperators = [null, '15'];

splitArray(myArray, mySeperators)

should result in that:

[[], [5, 'whazzup?', object], [34.6]]

the source array can contain the seperators multiple times. how to accomplish this?

when it makes solution easier, i'm using mootools as base library.

3
  • can there be multiple nulls/15's? Commented Aug 3, 2012 at 18:00
  • i added the answers to your questions to the question text. Commented Aug 3, 2012 at 18:07
  • just loop on the original array, every time checking if it is a separator (loop on the list of separators) and create new arrays as needed. This might seem like slow or doing extra work... but it is exactly what it is going on behind the doors of indexOf or reduce Commented Aug 3, 2012 at 18:21

4 Answers 4

4

Given ECMAScript 5, it is possible to accomplish this with the use of Array#reduce:

myArray.reduce(function(currentArrays, nextItem) {
    if(~mySeparators.indexOf(nextItem))
        currentArrays.push([]);
    else
        currentArrays[currentArrays.length - 1].push(nextItem);

    return currentArrays;
}, [[]]);

I have no experience with MooTools; however, it appears to polyfill Array#reduce, if backwards-compatibility is required.

Sign up to request clarification or add additional context in comments.

Comments

1

Answer assumes Array.indexOf is supported

function splitArray(orgArr, splits){
    var i, newArr=[], vals = orgArr.slice();  //clone the array so we do not change the orginal
    for (i=vals.length-1;i>=0;i--) {  //loop through in reverse order
       if (splits.indexOf(vals[i]) !== -1) {  //if we have a match time to do a split
         newArr.unshift( vals.splice(i+1, vals.length-i) ); //grab the indexes to the end and append it to the array
         vals.pop();  //remove the split point
       }
    }
    newArr.unshift(vals);  //add any of the remaining items to the array
    return newArr;  //return the split up array of arrays
}

var myArray = [null, 5, 'whazzup?', {}, '15', 34.6];
var mySeperators = [null, '15'];
console.log( splitArray(myArray, mySeperators) );

Comments

1

try this :)

http://jsfiddle.net/baP66/1/

var myArray = [null, 5, 'whazzup?', {}, '15', 34.6];
var mySeperators = [null, '15'];

var splitArray = function(arr, aSep){
    var acc = [[]];
    var sp = function(){
        for (var i=0; i<arr.length; i++){
            var item = arr[i];
            var last = acc[acc.length-1];

            if (aSep.indexOf(item) > -1){
                acc.push([]);
            }else{
                last.push(item);
            }
        };
    };
    sp();

    return acc;
};

var res = splitArray(myArray, mySeperators);

console.log(res);

Comments

1

This should be pretty general across browsers and not require any libraries:

function splitArray(a, seps) {
  var i, res = [], parts = [];
  for (i = 0; i < a.length; i++) {
    if (seps.indexOf(a[i]) > -1) {
      res.push(parts);
      parts = [];
    } else {
      parts.push(a[i]);
    }
  }
  res.push(parts);
  return res;
}

If you need to support browsers without builtin indexOf support (e.g. IE 6-8) then add this polyfill first:

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

3 Comments

JavaScript supports only string keys in objects, therefore this may not work as intended. Moreover, this will break for all array elements x where x.toString() in {}.
Consider the test case splitArray(['null', 'toString'], ['null']). It currently results in [[],[],[]].
@Charmander, good call on the indexing, I've updated to use indexOf with polyfill option.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.