Reputation: 593
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
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
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
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
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