kenny
kenny

Reputation: 1247

Merge arrays only adding new elements

Hey I'm breaking my head over something that should be very simple. I have a few arrays

//input

var array1 = ["white", "white", "yellow"];
var array2 = ["white", "white", "yellow", "red"];
var array3 = ["white", "white", "yellow", "orange"];

//desired output

var result = ["white", "white", "yellow", "red", "orange"];

This should be a simple problem but I just haven't been able to wind my head around it. I tried by using a snapshot of the first array, then see if the color was already in the snapshot array remove it from the snapshot, put it in another snapshot etc... but I ended up with lines and lines of code. Couldn't even get it to work since I was deleting all "white" colors from the snapshot instead of just one and other things where going wrong.

Cans someone give me a second perspective, cause I'm running against a wall atm

My last attempt as asked to provide the code

    let attacks = entry.attacks;
    if(attacks !== undefined){
        let lastSnapshot = [];

        attacks.forEach(attack => {
            if(lastSnapshot.length === 0){
                attack.forEach(attackColor => {
                    lastSnapshot.push(attackColor)
                })                        
            }else{
                let newSnapshot = [];
                attack.forEach(attackColor => {
                    var start_index = lastSnapshot.findIndex(attackColor)
                    if(start_index !== -1){
                        var number_of_elements_to_remove = 1;
                        lastSnapshot.splice(start_index, number_of_elements_to_remove);                                
                    }

                    newSnapshot.push(attackColor)
                })
                lastSnapshot = newSnapshot;                              
            }
        })
    }

Upvotes: 4

Views: 146

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386736

You could use reduce for the arrays and a forEach for single items of the array for adding items to r.

Then a hash table is used to store the visited items and their last index of the temporary result array r. If no item is found, the actual value is pushed.

var array1 = ["white", "white", "yellow"],
    array2 = ["white", "white", "yellow", "red"],
    array3 = ["white", "white", "yellow", "orange"],
    result = [array1, array2, array3].reduce((r, a) => {
        var indices = Object.create(null);
        a.forEach(b => {
            var p = r.indexOf(b, indices[b] || 0);
            indices[b] = p === -1 ? r.push(b) : p + 1;
        });
        return r;
    });
    
console.log(result);

Upvotes: 4

A l w a y s S u n n y
A l w a y s S u n n y

Reputation: 38542

You can try this way also with Set, Spread and forEach.

var array1 = ["white", "white", "yellow"];
var array2 = ["white", "white", "yellow", "red"];
var array3 = ["white", "white", "yellow", "orange"];
var merged = Array.from(new Set(array2.concat(array3)));
var desired = [...array1];
merged.forEach(function(element, index) {
  if (array1.indexOf(element) == -1) {
    desired.push(element);
  }
})
console.log(desired)

Spread Syntax: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

Set: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set

forEach: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

Upvotes: 1

Related Questions