Conversion algorithm of a single-level list in a duplex?

There is an array that contains items of two types (although in the General case may be more than two, but until that is possible on this score). Specific objects are unimportant, may, for clarity, it will be numbers and letters. You need to combine consecutive elements of the same type in the dataset. For example:
[1, 2, a, b] => [[1, 2], [a, b]]
[1, 2, 3, a, 4, 5, b, 9, n, m] => [[1, 2, 3], [a], [4, 5], [b], [9], [n, m]]
[1] => [[1]]
[a] => [[a]]
[] => []

It seems to be not a difficult task but solution something well, very sloppy. You can surely have beautiful and elegant, but apparently I'm blunt.
August 23rd 19 at 10:32
5 answers
August 23rd 19 at 10:40
ES6 can be more elegant?
let arr = [...], result = [[]], cur = 0;
for(let val of arr)
 if(arr[cur].length == 0 || typeof arr[cur][0] == typeof val) arr[cur].shift(val);
 else cur++, arr[cur] = [val];
August 23rd 19 at 10:34
var arr = [1, 2, 3, 'a', 4, 5, 'b', 9, 'n', 'm'];
arr = arr.reduceRight(function(prev, el, i) {
 if (prev.length == 0 || 
 (typeof(el) != typeof(prev[0][0]))) {
prev.unshift([el]);
 } else {
prev[0].unshift(el);
}
 return prev;
}, []);
console.log(JSON.stringify(arr));

[[1,2,3],["a"],[4,5],["b"],[9],["n","m"]]
I did think about the methods reduce, but they seem to me not very clear.
In fact, I now vaguely understand how your code works :) - Trey.Emard commented on August 23rd 19 at 10:37
: reduce works is very simple. at the beginning of the set battery, then for each element in the array, calls a function that is passed the current value of the battery, the value of the current array element and its position. The function returns the new value of the accumulator.
reduceRight traverses array in reverse order, here it is more convenient to work continuously with the zero element of the battery. - Erling.Berni commented on August 23rd 19 at 10:40
: Actually, the same thing can be done on a conventional cycle.
var arr = [1, 2, 3, 'a', 4, 5, 'b', 9, 'n', 'm'];
var res = [];
for (let i = arr.length-1; i >= 0; i--) {
 if (res.length == 0 || 
 (typeof(arr[i]) != typeof(res[0][0]))) {
Res. unshift([arr[i]]);
 } else {
res[0].unshift(arr[i]);
}
}
console.log(JSON.stringify(res));
- Erling.Berni commented on August 23rd 19 at 10:43
August 23rd 19 at 10:36
Need to move the values one by one, remembering the current "class" values. If you change to create a new subarray in which to push another value.

Working example:

// the classifier returns the class name of
// refers to the passed value
// no matter how called classes, just in different ways
function classify(i) {
 if( typeof i === "number") return "my_number";
 return "my_string"; 
}

// groups in consecutive subarrays
// values of a class
group function(a) {
 var i, item, c={prev:null, curr:null}, result=[], to;

 for(i=0; i<a.length; i++) { item="a[i];" c.curr="classify(item);" if(!c.prev || c.prev !="=" c.curr) result.push([]); to="result[result.length-1];" } to.push(item); return result; }< code></a.length;>
August 23rd 19 at 10:38
That's what I gave birth and what can be called more or less decent:
function group (input) {

 var last = function (arr) {
 return arr[arr.length - 1];
}

 var output = [];
 input.forEach(function (el) {
 if (output.length === 0 || typeof(el) !== typeof(last(output)[0])) {
output.push([]);
}
last(output).push(el);
});

 return output;
}
August 23rd 19 at 10:42
we sat on cadavers - fell in love with "once-returning".
and by the way the problem seems to be a similar resource.
well, in General, a battery may optionally be an array, it may be an object in which to store the flags instead of institution variables using var or zapilivanija some more functions.
also - why run a "heavy" algorithm, if we input empty/one-element array? immediately return [array].
the only negative solutions to two times typeof is invoked in cases when it is not the same.
another cheat code - reduce will return the battery. a battery is an object. and to the property of an object (result) can be accessed via point.
we will not blindly add to the arrays, this is the current key of the iterator acc.i (which is incremented when there is another element type).
well, originally it = -1, because the first mismatch is last:false !== "a-type-value" plusnet it and it will become zero.
and yet, I like it because there is only one check, everything else is pretty straight forward.
no need to do validate the existence of initial values "flag" - the main thing is to ask them directly
groupByType function(array) {
 return (array.length < 2) ? [array] : array.reduce(function(acc, current) {
 if(typeof current != acc.last){
 acc.last=typeof current;
acc.result.push([]);
acc.i++;
}
acc.result[acc.i].push(current);
 return acc;
 }, { result: [], i: -1,last:false }).result;
};

OPDAT.:
after thinking and looking around - you can get rid of the iterator, it is not needed.
groupByType function(array) {
 return (array.length < 2) ? [array] : array.reduce(function(acc, current) {
 if(typeof current != acc.last){
 acc.last=typeof current;
acc.result.push([]);
}
acc.result[acc.result.length-1].push(current);
 return acc;
 }, { result: [] ,last:false }).result;
};
groupByType([1, 2, 3, 'a', 4, 5, 'b', 9, 'n', 'm']);
No, the task is absolutely practical from a real project (albeit with the prefix pet, but still).
While it is possible that somewhere and met. - Trey.Emard commented on August 23rd 19 at 10:45

Find more questions by tags AlgorithmsJavaScript