My initial state is like below and if new Book added or price is changed then new updated array is ing from service whose result i need to merge in my initial state.
const initialState = {
booksData: [
{"Code":"BK01","price":"5"},
{"code":"BK02","price":"30"},
{"code":"BK03","price":"332"},
{"code":"BK04","price":"123"}
]
};
Updated array from server with few records updated/new
data: [
{"Code":"BK01","price":"10"},
{"code":"BK02","price":"25"},
{"code":"BK05","price":"100"}
]
updated state should bee after merging updated array with old array.
booksData: [
{"Code":"BK01","price":"10"},
{"code":"BK02","price":"25"},
{"code":"BK03","price":"332"},
{"code":"BK04","price":"123"},
{"code":"BK05","price":"100"}
]
My initial state is like below and if new Book added or price is changed then new updated array is ing from service whose result i need to merge in my initial state.
const initialState = {
booksData: [
{"Code":"BK01","price":"5"},
{"code":"BK02","price":"30"},
{"code":"BK03","price":"332"},
{"code":"BK04","price":"123"}
]
};
Updated array from server with few records updated/new
data: [
{"Code":"BK01","price":"10"},
{"code":"BK02","price":"25"},
{"code":"BK05","price":"100"}
]
updated state should bee after merging updated array with old array.
booksData: [
{"Code":"BK01","price":"10"},
{"code":"BK02","price":"25"},
{"code":"BK03","price":"332"},
{"code":"BK04","price":"123"},
{"code":"BK05","price":"100"}
]
Share
Improve this question
edited May 21, 2020 at 11:08
vsync
130k59 gold badges340 silver badges421 bronze badges
asked Jan 11, 2018 at 13:52
user6742120user6742120
1752 gold badges2 silver badges15 bronze badges
1
- 2 Keep in mind you are not "merging" arrays, you are creating a brand new array. It's an important distinction. – Galupuf Commented Jan 11, 2018 at 13:56
4 Answers
Reset to default 9I would filter out elements of the old data that are in the new data, and concat.
const oldBooks = booksData.filter(book => !newData.some(newBook => newBook.code === book.code));
return oldBooks.concat(newData);
Keep in mind you must NOT push values into the old array. In your reducer you MUST create new instances, here a new array. 'concat' does that.
You can first merge both the array together and then reduce
it to remove duplicates like
var booksData = [
{"code":"BK01","price":"5"},
{"code":"BK02","price":"30"},
{"code":"BK03","price":"332"},
{"code":"BK04","price":"123"}
]
var newData = [
{"code":"BK01","price":"10"},
{"code":"BK02","price":"25"},
{"code":"BK05","price":"100"}
]
const result = [...newData, ...booksData].reduce((res, data, index, arr) => {
if (res.findIndex(book => book.code === data.code ) < 0) {
res.push(data);
}
return res;
}, [])
console.log(result);
Merge the two array and filter using 'Code' property
const initialState = {
booksData: [
{ "Code": "BK01", "price": "5" },
{ "code": "BK02", "price": "30" },
{ "code": "BK03", "price": "332" },
{ "code": "BK04", "price": "123" }
]
};
const data =
[
{ "Code": "BK01", "price": "10" },
{ "code": "BK02", "price": "25" },
{ "code": "BK05", "price": "100" }
]
let newState = [...initialState.booksData, ...data];
newState = newState.filter((obj, pos, arr) => {
return arr.map(mapObj => mapObj['Code']).indexOf(obj['Code']) !== pos;
});
console.log(newState);
Collection of Objects
Filter a merged array to pick only non-existent items by iterating every item in the merged array which its index is before the current index of the "parent" filter iterator
const mergedUnique = [
...[{id:1}, {id:2}, {id:3}],
...[{id:1}, {id:4}, {id:2}]
]
.filter((item, idx, arr) =>
!arr.some(({id}, subIdx) => subIdx < idx && id == item.id)
)
console.log( mergedUnique )
Basic technique for "simple" arrays
Merge some arrays and filter them to pick only non-existent items by checking if the same item exists anywhere before the current item's index in the merged array.
lastIndexOf
is used to check backwards, if the current value exists already, which contributes to keeping the order of the merged array in a certain way which might be desirable, which can only be achieved by checking backward and not forward.
Skip checking the first item - is obviously not a duplicate.
const mergedUniqe = [...[1,2,3], ...[1,3,4,5,2]] // [1, 2, 3, 1, 3, 4, 5, 2]
.filter((item, idx, arr) =>
!~arr.lastIndexOf(item, idx-1) || !idx
)
console.log( mergedUniqe )