Jorman Franzini
Jorman Franzini

Reputation: 339

Manipulate more javascript array based on another array

I've a strange thing to do but I don't know how to start

I start with this vars

var base = [1,1,1,2,3,5,7,9,14,19,28,40,56,114,232,330];
var sky = [0,0,0,3,4,5,6,7,8,9,10,11,12,14,16,17];
var ite = [64,52,23,38,13,15,6,4,6,3,2,1,2,1,1,1];

So to start all the 3 array have the same length and the very first operation is to see if there is a duplicate value in sky array, in this case the 0 is duplicated and only in this case is at the end, but all of time the sky array is sorted. So I've to remove all the duplicate (in this case 0) from sky and remove the corresponding items from base and sum the corresponding items on ite. So if there's duplicate on position 4,5 I've to manipulate this conditions. But let see the new 3 array:

var new_base = [1,2,3,5,7,9,14,19,28,40,56,114,232,330];
var new_sky = [0,3,4,5,6,7,8,9,10,11,12,14,16,17];
var new_ite = [139,38,13,15,6,4,6,3,2,1,2,1,1,1];

If you see the new_ite have 139 instead the 64,52,23, that is the sum of 64+52+23, because the first 3 items on sky are the same (0) so I remove two corresponding value from base and sky too and I sum the corresponding value into the new_ite array.

There's a fast way to do that? I thought a for loops but I stuck at the very first for (i = 0; i < sky.length; i++) lol, cuz I've no idea on how to manipulate those 3 array in that way

J

Upvotes: 2

Views: 163

Answers (5)

Redu
Redu

Reputation: 26201

Just with a single .reduce() in O(n) time you can do as follows; (I have used array destructuring at the assignment part. One might choose to use three .push()s though)

var base = [1,1,1,2,3,5,7,9,14,19,28,40,56,114,232,330],
     sky = [0,0,0,3,4,5,6,7,8,9,10,11,12,14,16,17],
     ite = [64,52,23,38,13,15,6,4,6,3,2,1,2,1,1,1],
 results = sky.reduce((r,c,i) => c === r[1][r[1].length-1] ? (r[2][r[2].length-1] += ite[i],r)
                                                           : ([r[0][r[0].length],r[1][r[1].length],r[2][r[2].length]] = [base[i],c,ite[i]],r),[[],[],[]]);
console.log(JSON.stringify(results));

Upvotes: 0

Grallen
Grallen

Reputation: 1680

atltag's answer is fastest. Please see:

https://repl.it/FBpo/5

Upvotes: 0

Ori Drori
Ori Drori

Reputation: 193358

You can use Array#reduce to create new arrays from the originals according to the rules:

var base = [1,1,1,2,3,5,7,9,14,19,28,40,56,114,232,330];
var sky = [0,0,0,3,4,5,6,7,8,9,10,11,12,14,16,17];
var ite = [64,52,23,38,13,15,6,4,6,3,2,1,2,1,1,1];

var result = sky.reduce(function(r, n, i) {
  var last = r.sky.length - 1;
  
  if(n === r.sky[last]) {
    r.ite[last] += ite[i];
  } else {
    r.base.push(base[i]);
    r.sky.push(n);
    r.ite.push(ite[i]);
  }
  
  return r;
}, { base: [], sky: [], ite: [] });

console.log('new base:', result.base.join(','));
console.log('new sky:', result.sky.join(','));
console.log('new ite:', result.ite.join(','));

Upvotes: 0

trincot
trincot

Reputation: 351403

I would suggest this solution where j is used as index for the new arrays, and i for the original arrays:

var base = [1,1,1,2,3,5,7,9,14,19,28,40,56,114,232,330];
var sky = [0,0,0,3,4,5,6,7,8,9,10,11,12,14,16,17];
var ite = [64,52,23,38,13,15,6,4,6,3,2,1,2,1,1,1];

var new_base = [], new_sky = [], new_ite = [];

var j = -1;
sky.forEach(function (sk, i) {
    if (!i || sk !== sky[i-1]) {
        new_ite[++j] = 0;
        new_base[j] = base[i];
        new_sky[j] = sk;
    }
    new_ite[j] += ite[i];
});

console.log('new_base = ' + new_base);
console.log('new_sky = ' + new_sky);
console.log('new_ite = ' + new_ite);

Upvotes: 0

alttag
alttag

Reputation: 1173

When removing elements from an array during a loop, the trick is to start at the end and move to the front. It makes many things easier.

for( var i = sky.length-1; i>=0; i--) {
    if (sky[i] == prev) {
        // Remove previous index from base, sky
        // See http://stackoverflow.com/questions/5767325/how-to-remove-a-particular-element-from-an-array-in-javascript
        base.splice(i+1, 1);
        sky.splice(i+1, 1);

        // Do sum, then remove
        ite[i] += ite[i+1];
        ite.splice(i+1, 1);
    }
    prev = sky[i];
}

I won't speak to whether this is the "fastest", but it does work, and it's "fast" in terms of requiring little programmer time to write and understand. (Which is often the most important kind of fast.)

Upvotes: 2

Related Questions