Reputation: 125
I'm trying to use a recursive call to concat a return array
Directions to this problem are: A stream of data is received and needs to be reversed.
Each segment is 8 bits long, meaning the order of these segments needs to be reversed, for example:
11111111 00000000 00001111 10101010 (byte1) (byte2) (byte3) (byte4) should become:
10101010 00001111 00000000 11111111 (byte4) (byte3) (byte2) (byte1) The total number of bits will always be a multiple of 8.
trying different combinations of things really...
function dataReverse(data) {
//split incoming array into array values consisting of 8 numbers each.
//var octGroups = data.length / 8;
var result = [];
//recursive call
function shuffler(array){
let input = array;
//base case
if(input.length === 0){
return result;
} else {
//concat result with 8 values at a time
let cache = input.splice(-8,8);
result.concat(cache);
return shuffler(input);
}
return result;
}
var reversed = shuffler(data);
//base case is if data.length === 0 return result else
//reverse iterate through array, concating to new return array
//return result
return reversed;
}
console.log(dataReverse([1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,0,1,0,1,0]));
it is expected to reverse through the input array, concating a result array with 8 values at a time starting at the end, but not reversing the order of the numbers.
My attempt above returns a zero length array. What have I done wrong?
Upvotes: 2
Views: 296
Reputation: 18515
You can chunk the array by 8 pieces each
and then just use Array.reverse and Array.flat. The benefit of this is that you get a nice functional, reusable, chain-able and very readable code.
Consider this:
let data = [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,0,1,0,1,0]
// utility function to chunk array by number
const chunkBy = (arr, by=2) => arr.reduce((r,c,i) => (i%by==0 ? r.push([c]) : r[r.length-1] = [...r[r.length-1], c], r), [])
let result = chunkBy(data, 8).reverse().flat()
console.log('in: ', data.join(''))
console.log('out: ', result.join(''))
Here is the chunkBy
function in more readable form:
let data = [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,0,1,0,1,0]
const chunkBy = (arr, by=2) => // default to chunks of 2
arr.reduce((acc, cur, index) => {
if(index % by == 0) // use modulo to check for the remainder
acc.push([cur]) // if exact then we start a new chunk
else // if not we keep adding to the previous chunk
acc[acc.length-1] = [...acc[acc.length-1], cur]
return acc
}, [])
console.log(chunkBy(data, 8))
If you are using lodash _.chunk
is already there:
let data = [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,0,1,0,1,0]
let result = _(data)
.chunk(8)
.reverse()
.flatten()
.value()
console.log(result.join(''))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Upvotes: 0
Reputation: 37755
concat returns a new array you need to assign it back to result
result = result.concat(cache);
And if you want each byte as string of 8 characters you can use join
result = result.concat(cache.join(''));
function dataReverse(data) {
//split incoming array into array values consisting of 8 numbers each.
//var octGroups = data.length / 8;
var result = [];
//recursive call
function shuffler(array) {
let input = array;
//base case
if (input.length === 0) {
return result;
} else {
//concat result with 8 values at a time
let cache = input.splice(-8, 8);
result = result.concat(cache);
return shuffler(input);
}
return result;
}
var reversed = shuffler(data);
//base case is if data.length === 0 return result else
//reverse iterate through array, concating to new return array
//return result
return reversed;
}
console.log(dataReverse([1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0]));
You can just loop over array create group of 8 byte each and then reverse and then reduce back to single array
let dataReverse = (data) => {
let count = 0
let temp = []
let group = data.reduce((op, inp) => {
temp.push(inp)
if (count === 8) {
op.push(temp)
temp = []
}
return op
}, [])
if (temp.length) group.push(temp)
return group.reverse().reduce((op,inp)=>op.concat(inp))
}
console.log(dataReverse([1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0]));
Upvotes: 1
Reputation: 813
Use join
instead of concat
function dataReverse(data) {
//split incoming array into array values consisting of 8 numbers each.
//var octGroups = data.length / 8;
var result = [];
//recursive call
function shuffler(array) {
let input = array;
//base case
if (input.length === 0) {
return result;
} else {
//concat result with 8 values at a time
let cache = input.splice(-8, 8);
result.push(cache.join(''));
return shuffler(input);
}
return result;
}
var reversed = shuffler(data);
//base case is if data.length === 0 return result else
//reverse iterate through array, concating to new return array
//return result
return reversed;
}
console.log(dataReverse([1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0]));
Upvotes: 3
Reputation: 44107
concat
returns an array - assign the result:
function dataReverse(data) {
//split incoming array into array values consisting of 8 numbers each.
//var octGroups = data.length / 8;
var result = [];
//recursive call
function shuffler(array) {
let input = array;
//base case
if (input.length === 0) {
return result;
} else {
//concat result with 8 values at a time
let cache = input.splice(-8, 8);
result = result.concat(cache);
return shuffler(input);
}
return result;
}
var reversed = shuffler(data);
//base case is if data.length === 0 return result else
//reverse iterate through array, concating to new return array
//return result
return reversed;
}
let reversed = dataReverse([1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0]);
//Code for pretty-printing in groups of 8
reversed = reversed.reduce((acc, curr, i) => {
const c = Math.floor(i / 8);
acc[c] = [].concat((acc[c] || []), curr);
return acc;
}, []);
console.log(reversed.map(e => e.join("")));
.as-console-wrapper {
max-height: 100% !important;
top: auto;
}
(Array chunk from this answer).
Upvotes: 0