merge two arrays including some fields from each - javascript

I want to merge two arrays using map function, the idea is to create a new array with some fields taken from first array and some fields from the second one.
The condition is the field name.
Here is list A:
[
{"name": "tom", "id": "1", "date": "1654"},
{"name": "jack", "id": "2", "date": "6544"},
{"name": "sarah", "id": "3", "date": "987"},
{"name": "william", "id": "4", "date": "654"},
{"name": "ronaldo", "id": "5", "date": "12345"}
]
and here is list B:
[
{"name": "tom", "age": "20", "school": "A", "password": "abcd"},
{"name": "jack", "age": "25", "school": "B", "password": "1234"}
]
as a result, it should return a merged version, but only some selected fields included:
[
{"name": "tom", "age": "20", "school": "A", "exists": true, , "date": "1654"},
{"name": "jack", "age": "25", "school": "B", "exists": true, "date": "6544"},
{"name": "sarah", "age": "", "school": "", "exists": false, "date": "987"},
{"name": "william", "age": "", "school": "", "exists": false, "date": "654"},
{"name": "ronaldo", "age": "", "school": "", "exists": false, "date": "12345"}
]
Here is my attempt to merge these two arrays, using map, but not very successful. Could somebody help me to achieve this?
const alldata = listA.map(u => listB.filter(oo => u.name === oo.name));

I used name as the key to find whether an entry from a is present in b and created the required list with appropriate values from both the lists.
a = [
{"name": "tom", "id": "1", "date": "1654"},
{"name": "jack", "id": "2", "date": "6544"},
{"name": "sarah", "id": "3", "date": "987"},
{"name": "william", "id": "4", "date": "654"},
{"name": "ronaldo", "id": "5", "date": "12345"}
];
b=[
{"name": "tom", "age": "20", "school": "A", "password": "abcd"},
{"name": "jack", "age": "25", "school": "B", "password": "1234"}
];
c = a.map(a1 => {
let b3 = b.find(b1=>b1.name === a1.name) || {};
return {name: a1.name, age: b3.age || "", school: b3.school || "", exists: b3.name != undefined, date: a1.date}
})
console.log(c)

with this answer you're not creating new arrays.
let a = [{"name": "tom","id": "1","date": "1654"},{"name": "jack","id": "2","date": "6544"},{"name": "sarah","id": "3","date": "987"},{"name": "william","id": "4","date": "654"},{"name": "ronaldo","id": "5","date": "12345"}],
b = [{"name": "tom","age": "20","school": "A","password": "abcd"},{"name": "jack","age": "25","school": "B","password": "1234"}];
a.forEach((key, index)=>{
let exists;
b.forEach((bkey, bindex)=>{
if(key.name==bkey.name){
a[index] = {...a[index], ...b[bindex]};
exists = bkey.age;
}
});
a[index].exists = !!exists;
});
console.log(a);

You are very close. Try this:
let arrA = [
{"name": "tom", "id": "1", "date": "1654"},
{"name": "jack", "id": "2", "date": "6544"},
{"name": "sarah", "id": "3", "date": "987"},
{"name": "william", "id": "4", "date": "654"},
{"name": "ronaldo", "id": "5", "date": "12345"}
];
let arrB = [
{"name": "tom", "age": "20", "school": "A", "password": "abcd"},
{"name": "jack", "age": "25", "school": "B", "password": "1234"}
];
let result = arrA.map(v => {
let fr = arrB.filter(f => v.name == f.name ) ;
let e = fr.length ? true : false;
fr = fr.length ? fr[0] : {age: "", school: "", password: "" };
//Construct the format you want on the final array
return {
name: v.name,
age: fr.age,
school: fr.school,
exists: e,
date: v.date
}
});
console.log( result );

Use map to create new array and filter to find the matched element from the second element
var a = [{
"name": "tom",
"id": "1",
"date": "1654"
},
{
"name": "jack",
"id": "2",
"date": "6544"
},
{
"name": "sarah",
"id": "3",
"date": "987"
},
{
"name": "william",
"id": "4",
"date": "654"
},
{
"name": "ronaldo",
"id": "5",
"date": "12345"
}
]
var b = [{
"name": "tom",
"age": "20",
"school": "A",
"password": "abcd"
},
{
"name": "jack",
"age": "25",
"school": "B",
"password": "1234"
}
]
var c = a.map(function(item) {
let d = b.filter(function(items) {
return item.name === items.name;
})
if (d.length > 0) {
item.age = d[0].age;
item.school = d[0].school;
item.password = d[0].password
}
return item;
})
console.log(c)

const list1 = [
{"name": "tom", "id": "1", "date": "1654"},
{"name": "jack", "id": "2", "date": "6544"},
{"name": "sarah", "id": "3", "date": "987"},
{"name": "william", "id": "4", "date": "654"},
{"name": "ronaldo", "id": "5", "date": "12345"}
];
const list2 = [
{"name": "tom", "age": "20", "school": "A", "password": "abcd"},
{"name": "jack", "age": "25", "school": "B", "password": "1234"}
];
const merged = list1.map(item => {
const list2Match = list2.filter(i => i.name === item.name)[0];
const obj = list2Match ? {school: list2Match.school, age: list2Match.age, exists: true} : { school: '', age: '', exists: false};
return {school:obj.school, age: obj.age, exists: obj.exists, name: item.name, date: item.date };
});

Related

Replacing content of array on the basis of property

I am working on an angular application. I have two arrays as follows:
array1 = [
{
Name: "Jack",
Id: "1",
Location: "UK"
},
{
Name: "Rose",
Id: "2",
Location: "USA"
},
{
Name: "Mary",
Id: "3",
Location: "India"
}
];
array2 = [
{
Name: "Raj",
Id: "5",
Location: "UK"
},
{
Name: "John",
Id: "2",
Location: "Germany"
},
{
Name: "Maria",
Id: "3",
Location: "Canada"
}
];
I want a resultant array such that If "Id" of any element of array1 matches "Id" of any element in array2, then whole data for that particular "Id" should be replaced in array2. So my resulArray will look as follows:
resultArray = [
{
Name: "Raj",
Id: "5",
Location: "UK"
},
{
Name: "Rose",
Id: "2",
Location: "USA"
},
{
Name: "Mary",
Id: "3",
Location: "India"
}
];
So Id= 2 and Id =3 of array 1 matches in array2, so data of Id=2 and Id=3 in array2 are replaced by that of array1. How can I do it?
You need map and find here. You can put an OR condition that if value is present in array1 if so then will pick the object from array1 otherwise the current object will be chosen.
var array2=[ { "Name": "Raj", "Id": "5", "Location": "UK" }, { "Name": "John", "Id": "2", "Location": "Germany" }, { "Name": "Maria", "Id": "3", "Location": "Canada" }];
var array1= [{ "Name": "Jack", "Id": "1", "Location": "UK"},{ "Name": "Rose", "Id": "2", "Location": "USA"},{ "Name": "Mary", "Id": "3", "Location": "India"}];
var result = array2.map(p=>(array1.find(k=>k.Id==p.Id) || p));
console.log(result);
I hope this helps.
You can use reduce and find function for your requirement
array2.reduce((acc, c) => {
var existed = array1.find(a=>a.Id == c.Id);
if(existed){
c.Name = existed.Name;
}
return c;
}, [])
var array1= [
{
"Name": "Jack",
"Id": "1",
"Location": "UK"
},
{
"Name": "Rose",
"Id": "2",
"Location": "USA"
},
{
"Name": "Mary",
"Id": "3",
"Location": "India"
}
]
var array2=[
{
"Name": "Raj",
"Id": "5",
"Location": "UK"
},
{
"Name": "John",
"Id": "2",
"Location": "Germany"
},
{
"Name": "Maria",
"Id": "3",
"Location": "Canada"
}
];
array2.reduce((acc, c) => {
var existed = array1.find(a=>a.Id == c.Id);
if(existed){
c.Name = existed.Name;
}
return c;
}, [])
console.log(array2)

Sorting API JSON response using Javascript

I am getting below response on hitting DoctorData.api and want to sort them all with their 'ID'. Can someone show me how to sort the Output JSON data and display it same format.
Kindly Excuse my coding skills, this is my second test case. I am new to JS.
var doctorIDgeturl = geturl.geturls.getapiUrl; //'getapiUrl' is Doctor Get API
var res = await api.getRequest(doctorIDgeturl);
logger.logger().info('GET_data = ', JSON.stringify(res.data, null, 2));
var rescount = Object.keys(res.data.data.doctorList); //doctorList is the API response object for above GET API
console.log("This is Sorted Id: ");
const sortedResponse = sort(res.data, r => r.doctorListModels.associateId, ['asc']) //using ascending order to sort
console.log(sortedResponse);
Current output:
{
"message": "Record Found",
"data": {
"DoctorsList": [
{
"id": "10",
"name": "William",
"launch_date": "2018-01-24T00:00:00.000-05:00"
},
{
"id": "2",
"name": "Snow",
"launch_date": "2017-08-14T00:00:00.000-05:00"
},
{
"id": "33",
"name": "Thomas",
"launch_date": "2018-11-29T00:00:00.000-05:00"
},
{
"id": "3",
"name": "Ismail",
"launch_date": "2018-11-29T00:00:00.000-05:00"
},
{
"id": "5",
"name": "Jackson",
"launch_date": "2018-04-10T00:00:00.000-05:00"
}
Expected output after sorting:
{
"message": "Record Found",
"data": {
"DoctorsList": [
{
"id": "2",
"name": "Snow",
"launch_date": "2017-08-14T00:00:00.000-05:00"
},
{
"id": "3",
"name": "Ismail",
"launch_date": "2018-11-29T00:00:00.000-05:00"
},
{
"id": "5",
"name": "Jackson",
"launch_date": "2018-04-10T00:00:00.000-05:00"
},
{
"id": "10",
"name": "William",
"launch_date": "2018-01-24T00:00:00.000-05:00"
},
{
"id": "33",
"name": "Thomas",
"launch_date": "2018-11-29T00:00:00.000-05:00"
}
parseInt(r.doctorListModels.associateId) or +r.doctorListModels.associateId
it seems like it sorts the id as string not number
Sorry I can't comment because of low reputation, but here is solution.
const obj = {
"message": "Record Found",
"data": {
"DoctorsList": [{
"id": "10",
"name": "William",
"launch_date": "2018-01-24T00:00:00.000-05:00"
},
{
"id": "2",
"name": "Snow",
"launch_date": "2017-08-14T00:00:00.000-05:00"
},
{
"id": "33",
"name": "Thomas",
"launch_date": "2018-11-29T00:00:00.000-05:00"
},
{
"id": "3",
"name": "Ismail",
"launch_date": "2018-11-29T00:00:00.000-05:00"
},
{
"id": "5",
"name": "Jackson",
"launch_date": "2018-04-10T00:00:00.000-05:00"
}]
}
}
const sortedResponse = obj.data.DoctorsList.sort(function(a, b) { return parseInt(a.id) - parseInt(b.id) });
console.log(sortedResponse)
const obj = {
"message": "Record Found",
"data": {
"DoctorsList": [{
"id": "10",
"name": "William",
"launch_date": "2018-01-24T00:00:00.000-05:00"
},
{
"id": "2",
"name": "Snow",
"launch_date": "2017-08-14T00:00:00.000-05:00"
},
{
"id": "33",
"name": "Thomas",
"launch_date": "2018-11-29T00:00:00.000-05:00"
},
{
"id": "3",
"name": "Ismail",
"launch_date": "2018-11-29T00:00:00.000-05:00"
},
{
"id": "5",
"name": "Jackson",
"launch_date": "2018-04-10T00:00:00.000-05:00"
}
]
}}
obj.data.DoctorsList = obj.data.DoctorsList.sort((a, b) => parseInt(a.id) > parseInt(b.id));
console.log(obj)

How to access two data stored in array object that are linked by one field?

I have a REST API from which i am fetching the json data and storing them in array. The API looks like below:
[
{
"id": "100",
"name": "Person1",
"number": "+91-8980439023"
},
{
"id": "102",
"name": "Person2",
"number": "+91-5980339023"
},
{
"id": "105",
"name": "Person3",
"number": "+91-8980439023"
},
{
"id": "101",
"name": "Person4",
"number": "+91-8980439023",
"parent": "105"
},
{
"id": "110",
"name": "Person5",
"number": "+91-8980439023"
},
{
"id": "115",
"name": "Person6",
"number": "+91-9834295899",
"parent": "100"
}
]
Some of the data have "parent" field.The value in the "parent" field is the "id" of the other data. Now i want to store these data which have reference in the "parent" field of other data in a separate array. For example:
The data with id=101 has "parent" key with value 105 which in turn is the id of the 3rd data.So the data with id=105 should be stored in separate array.
How can i do in a simple and scalable way?
Try
let parents = data.filter(d=> data.some(c=> c.parent==d.id));
let data = [
{
"id": "100",
"name": "Person1",
"number": "+91-8980439023"
},
{
"id": "102",
"name": "Person2",
"number": "+91-5980339023"
},
{
"id": "105",
"name": "Person3",
"number": "+91-8980439023"
},
{
"id": "101",
"name": "Person4",
"number": "+91-8980439023",
"parent": "105"
},
{
"id": "110",
"name": "Person5",
"number": "+91-8980439023"
},
{
"id": "115",
"name": "Person6",
"number": "+91-9834295899",
"parent": "100"
}
];
let parents = data.filter(d=> data.some(c=> c.parent==d.id));
console.log(parents);
To have O(2n) complexity first put parents id to some hash table and then filter
let data = [
{
"id": "100",
"name": "Person1",
"number": "+91-8980439023"
},
{
"id": "102",
"name": "Person2",
"number": "+91-5980339023"
},
{
"id": "105",
"name": "Person3",
"number": "+91-8980439023"
},
{
"id": "101",
"name": "Person4",
"number": "+91-8980439023",
"parent": "105"
},
{
"id": "110",
"name": "Person5",
"number": "+91-8980439023"
},
{
"id": "115",
"name": "Person6",
"number": "+91-9834295899",
"parent": "100"
}
];
let hash = {};
data.forEach(d=> hash[d.parent]=d);
let parents = data.filter(d=> d.id in hash);
console.log(parents);
You can use map method and store elements into Map collection to have O(1) when you map items:
const maps = new Map(fooArray.map(o=> [o.id, o]))
const result = fooArray.map(({parent, ...rest}) => {
let obj = {...rest};
parent ? (obj.parent = [maps.get(parent)]) : null;
return obj;
})
console.log(result);
An example:
const fooArray = [
{
"id": "100",
"name": "Person1",
"number": "+91-8980439023"
},
{
"id": "102",
"name": "Person2",
"number": "+91-5980339023"
},
{
"id": "105",
"name": "Person3",
"number": "+91-8980439023"
},
{
"id": "101",
"name": "Person4",
"number": "+91-8980439023",
"parent": "105"
},
{
"id": "110",
"name": "Person5",
"number": "+91-8980439023"
},
{
"id": "115",
"name": "Person6",
"number": "+91-9834295899",
"parent": "100"
}
]
const maps = new Map(fooArray.map(o=> [o.id, o]))
const result = fooArray.map(({parent, ...rest}) => {
let obj = {...rest};
parent ? (obj.parent = [maps.get(parent)]) : null;
return obj;
})
console.log(result);
You can also collect all parent ids and then find records which has the same id as some parent:
let par_ids = [];
records.forEach(pid =>{
for (let [key, value] of Object.entries(pid)) {
key == 'parent' ? par_ids.push(value) : null;
}
})
let res = records.filter(ob => par_ids.includes(ob.id))
let records = [
{
"id": "100",
"name": "Person1",
"number": "+91-8980439023"
},
{
"id": "102",
"name": "Person2",
"number": "+91-5980339023"
},
{
"id": "105",
"name": "Person3",
"number": "+91-8980439023"
},
{
"id": "101",
"name": "Person4",
"number": "+91-8980439023",
"parent": "105"
},
{
"id": "110",
"name": "Person5",
"number": "+91-8980439023"
},
{
"id": "115",
"name": "Person6",
"number": "+91-9834295899",
"parent": "100"
}
];
let par_ids = [];
records.forEach(pid =>{
for (let [key, value] of Object.entries(pid)) {
key == 'parent' ? par_ids.push(value) : null;
}
})
let res = records.filter(ob => par_ids.includes(ob.id))
console.log(res)

Get difference between two nested arrays in javascript

I wanted to get the difference between two arrays which is nested.
let firstArray = {
"family": "BLUE",
"globalThreshold": "2.0",
"levelData": [
{
"name": "India",
"value": "4.0",
"count": [
{
"id": "21",
"countName": "ABC",
"countThreshold": "7.0"
},
{
"id": "22",
"workscopeName": "DEF",
"countThreshold": "4242"
}
]
},
{
"name": "FEDERAL EXPRESS CORPORATION",
"value": "1.0",
"count": [
{
"id": "5",
"countName": "ABC",
"countThreshold": "2.0"
},
{
"id": "6",
"countName": "DEF",
"countThreshold": "3.0"
}
]
}
]
}
let changedArray= {
"family": "BLUE",
"globalThreshold": "2.0",
"levelData": [
{
"name": "India",
"value": "5",
"count": [
{
"id": "21",
"countName": "ABC",
"countThreshold": "7.0"
},
{
"id": "22",
"workscopeName": "DEF",
"countThreshold": "4242"
}
]
},
{
"name": "FEDERAL EXPRESS CORPORATION",
"value": "1.0",
"count": [
{
"id": "5",
"countName": "ABC",
"countThreshold": "60"
},
{
"id": "6",
"countName": "DEF",
"countThreshold": "3.0"
}
]
}
]
}
Expected result:
let finalArray = {
"family": "BLUE",
"globalThreshold": "2.0",
"levelData": [
{
"name": "India",
"value": "5",
"count": []
},
{
"name": "FEDERAL EXPRESS CORPORATION",
"value": "1.0",
"count": [
{
"id": "5",
"countName": "ABC",
"countThreshold": "60"
}
]
}
]
}
I would like to track the diffference based on the value property inside 'levelData' array and countThreshold inside count array.
i tried repeating two arrays in for loop but was not able to repeat Any simultaneously as its nested.Do let me know any quick approach..
Thanks
Try using map to iterate for each levelData finding their respective in firstArray by name then filter by matching its properties:
let firstArray={"family":"BLUE","globalThreshold":"2.0","levelData":[{"name":"India","value":"4.0","count":[{"id":"21","countName":"ABC","countThreshold":"7.0"},{"id":"22","workscopeName":"DEF","countThreshold":"4242"}]},{"name":"FEDERAL EXPRESS CORPORATION","value":"1.0","count":[{"id":"5","countName":"ABC","countThreshold":"2.0"},{"id":"6","countName":"DEF","countThreshold":"3.0"}]}]};
let changedArray={"family":"BLUE","globalThreshold":"2.0","levelData":[{"name":"India","value":"5","count":[{"id":"21","countName":"ABC","countThreshold":"7.0"},{"id":"22","workscopeName":"DEF","countThreshold":"4242"}]},{"name":"FEDERAL EXPRESS CORPORATION","value":"1.0","count":[{"id":"5","countName":"ABC","countThreshold":"60"},{"id":"6","countName":"DEF","countThreshold":"3.0"}]}]}
var arr = changedArray.levelData.map(ele => {
var count = firstArray.levelData.find(x => x.name == ele.name).count;
ele.count = ele.count.filter(x => !count.some(y => x.id == y.id && x.countThreshold == y.countThreshold));
return ele;
})
console.log(arr);

Group by JSON array using jQuery

I have a set of JSON array and I want the result to be grouped by the "Id" column. I will not use underscore.js for this, as this can't be used in our project. The only option is to do it with jQuery. My source array and expected results are below.
var origObj = [{ "Id": "1", "name": "xxx", "age": "22" },
{ "Id": "1", "name": "yyy", "age": "15" },
{ "Id": "5", "name": "zzz", "age": "59" }]
var output = [{"1": [{ "Id": "1", "name": "xxx", "age": "22" },
{ "Id": "1", "name": "yyy", "age": "15" }],
"5": [{ "Id": "5", "name": "zzz", "age": "59" }]}]
You can use Array.prototype.reduce to get this done. Check this post for more details https://stackoverflow.com/a/22962158/909535 Extending on that this is what you would need
var data= [{ "Id": "1", "name": "xxx", "age": "22" },
{ "Id": "1", "name": "yyy", "age": "15" },
{ "Id": "5", "name": "zzz", "age": "59" }];
console.log(data.reduce(function(result, current) {
result[current.Id] = result[current.Id] || [];
result[current.Id].push(current);
return result;
}, {}));
Try
var origObj = [{ "Id": "1", "name": "xxx", "age": "22" },
{ "Id": "1", "name": "yyy", "age": "15" },
{ "Id": "5", "name": "zzz", "age": "59" }], output;
output = [origObj.reduce((a,c) => (a[c.Id]=(a[c.Id]||[]).concat(c),a) ,{})];
console.log(output);

Categories

Resources