1

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"}];
2
  • I think your data structure should be different use a map of key-value which the key is the city_id and the value is the object. Besides that, you can combine the for loops to one loop instead of two Commented Jan 20, 2022 at 12:56
  • 1
    Don't use for...in on arrays Commented Jan 20, 2022 at 13:42

4 Answers 4

2

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; }

Sign up to request clarification or add additional context in comments.

Comments

0

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>

Comments

0

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 });

Comments

0

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"}]];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.