bombombs
bombombs

Reputation: 593

Transfer some elements from one array to another array

This is my attempt to transfer from a row of data from one object to another. I am wondering if there is a more efficient way to do it.

Elements within the list selected_city_codes would be the ones to be transferred from airport_data_2 to airport_data_1.

original data and attempt

airport_data_1 = [{"departure_time":"12:00","arrival_time":"03:00","city_id":"BOS"},  
{"departure_time" :"12:00","arrival_time":"03:00","city_id":"BOS"},
{"departure_time" :"01:00","arrival_time":"04:00","city_id":"SFO"},
{"departure_time" :"03:00","arrival_time":"05:00","city_id":"BOS"},
{"departure_time" :"03:00","arrival_time":"05:00","city_id":"SFO"}]; 


airport_data_2 = [{"departure_time" :"03:00","arrival_time":"05:00","city_id":"DEN"},
{"departure_time" :"04:00","arrival_time":"06:00","city_id":"SJC"},
{"departure_time" :"04:00","arrival_time":"06:00","city_id":"JFK"},
{"departure_time" :"06:00","arrival_time":"09:00","city_id":"SJC"}]; 


selected_city_codes = ['SJC','JFK']; //items to remove from `airport_data_2` to `airport_data_1`

function move_and_delete_data(obj_1, obj_2,list){
    for(i in list) { 
        for (j in obj_2){
            if(list[i] == obj_2[j].city_id){
                obj_1.push(obj_2[j]);
            }
        }
    }
    for(i in list) { 
        obj_2 = obj_2.filter(item => item.city_id != list[i]);
    }
}

move_and_delete_data(airport_data_1, airport_data_2,selected_city_codes);

Desired Result

airport_data_1 = [{"departure_time":"12:00","arrival_time":"03:00","city_id":"BOS"},  
{"departure_time" :"12:00","arrival_time":"03:00","city_id":"BOS"},
{"departure_time" :"01:00","arrival_time":"04:00","city_id":"SFO"},
{"departure_time" :"03:00","arrival_time":"05:00","city_id":"BOS"},
{"departure_time" :"03:00","arrival_time":"05:00","city_id":"SFO"},
{"departure_time" :"04:00","arrival_time":"06:00","city_id":"SJC"},
{"departure_time" :"04:00","arrival_time":"06:00","city_id":"JFK"},
{"departure_time" :"06:00","arrival_time":"09:00","city_id":"SJC"}];

airport_data_2 = [{"departure_time" :"03:00","arrival_time":"05:00","city_id":"DEN"}];

Upvotes: 1

Views: 130

Answers (4)

customcommander
customcommander

Reputation: 18901

We can build a curried prop_is function that takes the name of a property and a predicate then an object and apply the predicate on that property:

const prop_is = (k, pred) => o => pred(o[k]);

We can build a curried includes function that takes a list then a value and check if a value is in that list:

const includes = xs => x => xs.includes(x);

Then we can build some filter functions:

const city_filter = prop_is('city_id', includes(['JFK', 'SJC']));
const time_filter = prop_is('arrival_time', includes(['06:00']));

And apply them:

airport_data_2.filter(city_filter);
//=>  [ {"departure_time" :"04:00","arrival_time":"06:00","city_id":"SJC"}
//=>  , {"departure_time" :"04:00","arrival_time":"06:00","city_id":"JFK"}
//=>  , {"departure_time" :"06:00","arrival_time":"09:00","city_id":"SJC"}];

airport_data_2.filter(city_filter).filter(time_filter);
//=>  [ {"departure_time" :"04:00","arrival_time":"06:00","city_id":"SJC"}
//=>  , {"departure_time" :"04:00","arrival_time":"06:00","city_id":"JFK"}];

airport_data_2.filter(x => city_filter(x) && time_filter(x));
//=>  [ {"departure_time" :"04:00","arrival_time":"06:00","city_id":"SJC"}
//=>  , {"departure_time" :"04:00","arrival_time":"06:00","city_id":"JFK"}];

And to answer your question:

airport_data_1.concat(airport_data_2.filter(city_filter));
airport_data_2.filter(x => !city_filter(x));

You could also build a partition function that takes a predicate and list and separate the elements that satisfy the predicate from the ones that don't:

const partition = pred => xs =>
  xs.reduce((ys, x) => (ys[+pred(x)].push(x), ys), [[], []]);

const split_by_city = partition(city_filter);

split_by_city(airport_data_2);
//=> [ [ {"departure_time" :"03:00","arrival_time":"05:00","city_id":"DEN"}]
//=> , [ {"departure_time" :"04:00","arrival_time":"06:00","city_id":"SJC"}
//=>   , {"departure_time" :"04:00","arrival_time":"06:00","city_id":"JFK"}
//=>   , {"departure_time" :"06:00","arrival_time":"09:00","city_id":"SJC"}]];

Upvotes: 0

pilchard
pilchard

Reputation: 12920

No need for anything fancy, you can iterate the second array once in a for loop and push/splice objects that are included in the passed list.

function move_and_delete_data(obj_1, obj_2, list) {
  for (let i = 0; i < obj_2.length; ) {
    if (list.includes(obj_2[i].city_id)) {
      obj_1.push(...obj_2.splice(i, 1));
      continue;
    }
    i++;
  }
}

const airport_data_1 = [{"departure_time":"12:00","arrival_time":"03:00","city_id":"BOS"}, {"departure_time" :"12:00","arrival_time":"03:00","city_id":"BOS"}, {"departure_time" :"01:00","arrival_time":"04:00","city_id":"SFO"}, {"departure_time" :"03:00","arrival_time":"05:00","city_id":"BOS"}, {"departure_time" :"03:00","arrival_time":"05:00","city_id":"SFO"}]; 
const airport_data_2 = [{"departure_time" :"03:00","arrival_time":"05:00","city_id":"DEN"}, {"departure_time" :"04:00","arrival_time":"06:00","city_id":"SJC"}, {"departure_time" :"04:00","arrival_time":"06:00","city_id":"JFK"}, {"departure_time" :"06:00","arrival_time":"09:00","city_id":"SJC"}]; 
const selected_city_codes = ['SJC','JFK']; //items to remove from `airport_data_2` to `airport_data_1`

move_and_delete_data(airport_data_1, airport_data_2, selected_city_codes);

console.log({ airport_data_1, airport_data_2 });

You could also consolidate splice calls by using a counter to identify runs of consecutive elements that fulfill the predicate and splice/push once for each run.

function move_and_delete_data(obj_1, obj_2, list) {
  list = new Set(list);
  let i = 0;
  while (i < obj_2.length) {
    let j = i, c = 0;
    while (i < obj_2.length && list.has(obj_2[i++].city_id)) c++;
    if (c) obj_1.push(...obj_2.splice(j, c));
  }
}

const airport_data_1 = [{"departure_time":"12:00","arrival_time":"03:00","city_id":"BOS"}, {"departure_time" :"12:00","arrival_time":"03:00","city_id":"BOS"}, {"departure_time" :"01:00","arrival_time":"04:00","city_id":"SFO"}, {"departure_time" :"03:00","arrival_time":"05:00","city_id":"BOS"}, {"departure_time" :"03:00","arrival_time":"05:00","city_id":"SFO"}]; 
const airport_data_2 = [{"departure_time" :"03:00","arrival_time":"05:00","city_id":"DEN"}, {"departure_time" :"04:00","arrival_time":"06:00","city_id":"SJC"}, {"departure_time" :"04:00","arrival_time":"06:00","city_id":"JFK"}, {"departure_time" :"06:00","arrival_time":"09:00","city_id":"SJC"}]; 
const selected_city_codes = ['SJC','JFK']; //items to remove from `airport_data_2` to `airport_data_1`

move_and_delete_data(airport_data_1, airport_data_2, selected_city_codes);

console.log({ airport_data_1, airport_data_2 });

Upvotes: 0

Terry Lennox
Terry Lennox

Reputation: 30695

I'd suggest using spread syntax along with Array.filter() and Array.includes() to get the required arrays.

The first array will include all elements in airport_data_1, along with the matching elements in airport_data_2.

The second array will include only the filtered elements from airport_data_2.

The arrays will be modified in place.

airport_data_1 = [{"departure_time":"12:00","arrival_time":"03:00","city_id":"BOS"}, {"departure_time" :"12:00","arrival_time":"03:00","city_id":"BOS"}, {"departure_time" :"01:00","arrival_time":"04:00","city_id":"SFO"}, {"departure_time" :"03:00","arrival_time":"05:00","city_id":"BOS"}, {"departure_time" :"03:00","arrival_time":"05:00","city_id":"SFO"}]; 
airport_data_2 = [{"departure_time" :"03:00","arrival_time":"05:00","city_id":"DEN"}, {"departure_time" :"04:00","arrival_time":"06:00","city_id":"SJC"}, {"departure_time" :"04:00","arrival_time":"06:00","city_id":"JFK"}, {"departure_time" :"06:00","arrival_time":"09:00","city_id":"SJC"}]; 

selected_city_codes = ['SJC','JFK']; //items to remove from `airport_data_2` to `airport_data_1`

function move_and_delete_data(obj_1, obj_2, list) {
    obj_1.push(...obj_2.filter(item => list.includes(item.city_id))); 
    obj_2.splice(0, obj_2.length, obj_2.filter(item => !list.includes(item.city_id)))
}

move_and_delete_data(airport_data_1, airport_data_2, selected_city_codes)

console.log({ airport_data_1, airport_data_2 })
.as-console-wrapper { max-height: 100% !important; top: 0; }

Here's another version that will return the updated arrays rather than modifying in place:

airport_data_1 = [{"departure_time":"12:00","arrival_time":"03:00","city_id":"BOS"}, {"departure_time" :"12:00","arrival_time":"03:00","city_id":"BOS"}, {"departure_time" :"01:00","arrival_time":"04:00","city_id":"SFO"}, {"departure_time" :"03:00","arrival_time":"05:00","city_id":"BOS"}, {"departure_time" :"03:00","arrival_time":"05:00","city_id":"SFO"}]; 
airport_data_2 = [{"departure_time" :"03:00","arrival_time":"05:00","city_id":"DEN"}, {"departure_time" :"04:00","arrival_time":"06:00","city_id":"SJC"}, {"departure_time" :"04:00","arrival_time":"06:00","city_id":"JFK"}, {"departure_time" :"06:00","arrival_time":"09:00","city_id":"SJC"}]; 

selected_city_codes = ['SJC','JFK']; //items to remove from `airport_data_2` to `airport_data_1`

function move_and_delete_data(obj_1, obj_2, list) {
    return [ 
        [...obj_1, ...obj_2.filter(item => list.includes(item.city_id))],
        obj_2.filter(item => !list.includes(item.city_id))
    ];
}

[airport_data_1, airport_data_2] = move_and_delete_data(airport_data_1, airport_data_2, selected_city_codes)

console.log({ airport_data_1, airport_data_2 })
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 2

KooiInc
KooiInc

Reputation: 122936

Append a filtered airport_data_2 to airport_data_1 using the spread syntax.

Next re-assign airport_data_2, using a filter to remove the previously appended elements (so the inverse of the first filter).

let airport_data_1 = [{"departure_time":"12:00","arrival_time":"03:00","city_id":"BOS"},  
{"departure_time" :"12:00","arrival_time":"03:00","city_id":"BOS"},
{"departure_time" :"01:00","arrival_time":"04:00","city_id":"SFO"},
{"departure_time" :"03:00","arrival_time":"05:00","city_id":"BOS"},
{"departure_time" :"03:00","arrival_time":"05:00","city_id":"SFO"}]; 

let airport_data_2 = [{"departure_time" :"03:00","arrival_time":"05:00","city_id":"DEN"},
{"departure_time" :"04:00","arrival_time":"06:00","city_id":"SJC"},
{"departure_time" :"04:00","arrival_time":"06:00","city_id":"JFK"},
{"departure_time" :"06:00","arrival_time":"09:00","city_id":"SJC"}];

airport_data_1 = [...airport_data_1, ...airport_data_2.filter(r => r.city_id !== `DEN`)];
airport_data_2 = airport_data_2.filter(r => r.city_id === `DEN`);

document.querySelector(`pre`).textContent = `*airport_data_1
${JSON.stringify(airport_data_1, null, 2)}

*airport_data_2
${JSON.stringify(airport_data_2, null, 2)}`;
<pre></pre>

Upvotes: 0

Related Questions