How to loop over arrays to combine them into one JavaScript object? - javascript

I have three arrays, "lender", "names", "pageNumbers":
var lender = [
[
{ "name": "IFC", "amount": 50 },
{ "name": "ABC", "amount": 10 }
],
[
{ "name": "DEF", "amount": 40 },
{ "name": "GHI", "amount": 100 }
]
]
var names = ["Gary", "Neil", "Luke", "Ben"]
var pageNumbers = [["page 0"], ["page 1"]]
I want to combine these three arrays into one JavaScript object that looks like this:
page 0 = {
Gary = {
financiers = {
name = IFC
}
},
Neil = {
financiers = {
name = ABC
}
}
}, page 1 = {
Luke = {
financiers = {
name = DEF
}
},
Ben = {
financiers = {
name = GHI
}
}
}
}
I thought looping over the arrays and assigning them to a predefined object would be the best way to do that:
//Predefined Object
var lenderObj = {
"lenders": {
[pageNumbers]:{
[names]: {}
}
}
//Loop
for (var j = 0; j < pageNumbers.length;j++) {
for (var i = 0; i < names.length; i++) {
lenderObj.lenders[pageNumbers[j]] = {
[names[i]]: {
financiers:lender[j][i]
}
}
}
}
But I'm not getting the right result, seems to only give me the last name (Ben) and then NULL as the value for 'financiers'. I can't seem to see what is wrong with what I have written. Any help would be great. Thanks.

Do it as below -
var lender = [
[{
"name": "IFC",
"amount": 50
},
{
"name": "ABC",
"amount": 10
}
],
[{
"name": "DEF",
"amount": 40
},
{
"name": "GHI",
"amount": 100
}
]
];
var names = ["Gary", "Neil", "Luke", "Ben"];
var pageNumbers = [
["page 0"],
["page 1"]
];
var lenderObj = {
"lenders": {
}
}
//Loop
var nameIterator = 0;
for(var i = 0; i < lender.length; i++) {
lenderObj.lenders[pageNumbers[i]] = {};
var lenderItem = lender[i];
for(var j = 0; j < lenderItem.length; j++) {
lenderObj.lenders[pageNumbers[i]][names[nameIterator]] = {};
lenderObj.lenders[pageNumbers[i]][names[nameIterator]].financiers = lenderItem[j];
nameIterator++;
}
}
console.log(lenderObj);

Using forEach and destructuring
var lender = [
[
{ name: "IFC", amount: 50 },
{ name: "ABC", amount: 10 },
],
[
{ name: "DEF", amount: 40 },
{ name: "GHI", amount: 100 },
],
];
var names = ["Gary", "Neil", "Luke", "Ben"];
var pageNumbers = [["page 0"], ["page 1"]];
const output = { lenders: {} };
pageNumbers.forEach(([page], pi) => {
output.lenders[page] = {};
lender[pi].forEach(
({ name }, li) =>
(output.lenders[page][names[2 * pi + li]] = { financiers: { name } })
);
});
console.log(output);

Related

Replace keys based on another array of objects

I have two array of objects, Based on one array I need to replace the key of another array. Tried to use Object.Keys() but could not achieve it. Kindly suggest
// **Input :**
let sim = {
"header": [{
"VKORG": "1000",
"VTWEG": "10"
},
{
"VKORG": "1000",
"VTWEG": "20"
}
]
}
// **Reference Array:**
let columns = [{
"FIELD": "VKORG",
"FIELD_DESC": "Sales Organization"
},
{
"FIELD": "VTWEG",
"FIELD_DESC": "Distribution Channel"
}
]
/// **Code I tried**
for (let i = 0; i < sim.header.length; i++) {
if (Object.keys(sim[i].header) === Object.keys(columns[i].header)) {
sim[i].header[columns[i].header.FIELD_DESC] = sim[i].header[Object.keys(sim[i].header)]
}
}
console.log(sim);
Expected Output:
output = {
"header": [{
"Sales Organization": "1000",
"Distribution Channel: "
10 "
},
{
"Sales Organization": "1000",
"Distribution Channel": "20"
}
]
}
Is not perfect but try this
let sim = {
"header": [
{
"VKORG": "1000",
"VTWEG": "10"
},
{
"VKORG": "1000",
"VTWEG": "20"
}
]
};
let columns = [
{
"FIELD": "VKORG",
"FIELD_DESC": "Sales Organization"
},
{
"FIELD": "VTWEG",
"FIELD_DESC": "Distribution Channel"
}
];
const filter = {};
for (let i = 0; i < columns.length; i++) {
filter[columns[i].FIELD] = columns[i].FIELD_DESC;
}
sim.header = sim.header.map(el => {
const keys = Object.keys(el);
const newObj = {}
for (const key of keys) {
newObj[filter[key]] = el[key];
}
return newObj;
});
console.log(sim);
Here is an approach using Map and array.map . We store the columns as key value pair in Map , then while traversing the sim.header , just get the value from the map for the particular key and update it .
let sim = {
"header": [{
"VKORG": "1000",
"VTWEG": "10"
},
{
"VKORG": "1000",
"VTWEG": "20"
}
]
}
let columns = [{
"FIELD": "VKORG",
"FIELD_DESC": "Sales Organization"
},
{
"FIELD": "VTWEG",
"FIELD_DESC": "Distribution Channel"
}
]
var map = new Map();
columns.forEach(obj => {
map.set(obj.FIELD, obj.FIELD_DESC);
})
sim.header = sim.header.map(obj => {
var tempObj = {};
Object.keys(obj).forEach(key => {
tempObj[map.get(key)] = obj[key]
})
return tempObj;
})
console.log(sim);

How to filter out objects if two keys are duplicate

const obj =
[
{
"id":"1",
"name":"a",
"email":"abc#gmail.com",
"expiryType":"premium"
},
{
"id":"2",
"name":"b",
"email":"abc#gmail.com",
"expiryType":"gold"
},
{
"id":"3",
"name":"b",
"email":"test#gmail.com",
"expiryType":"premium"
},
]
can somebody please help me how to filter out objects where email is same but i want to keep the one with expiry Type is premium ? How to achieve this using Javascript
Expected output would be
const obj =
[
{
"id":"1",
"name":"a",
"email":"abc#gmail.com",
"expiryType":"premium"
},
{
"id":"3",
"name":"b",
"email":"test#gmail.com",
"expiryType":"premium"
},
]
Assuming you want to keep the latest year's entry, you can keep a Map of the email addresses and years you've seen. See comments:
// The new list
const filtered = [];
// Known emails
const known = new Map();
// Loop through...
for (const entry of obj) {
// Get this email and expiry
const {email, expiryYear} = entry;
// Get the previous info if any
const previous = known.get(email);
if (previous) {
// If the previous one is older than this one,
// replace it with this one
if (previous.expiryYear < expiryYear) {
filtered[previous.index] = entry;
}
} else {
// Add this to the known list and the filtered array
known.set(email, {
index: filtered.length,
expiryYear
});
filtered.push(entry);
}
}
const obj = [
{
"id":"1",
"name":"a",
"email":"abc#gmail.com",
"expiryYear":"2020"
},
{
"id":"2",
"name":"a",
"email":"abc#gmail.com",
"expiryYear":"2019"
},
{
"id":"3",
"name":"b",
"email":"test#gmail.com",
"expiryYear":"2020"
},
];
// The new list
const filtered = [];
// Known emails
const known = new Map();
// Loop through...
for (const entry of obj) {
// Get this email and expiry
const {email, expiryYear} = entry;
// Get the previous info if any
const previous = known.get(email);
if (previous) {
// If the previous one is older than this one,
// replace it with this one
if (previous.expiryYear < expiryYear) {
filtered[previous.index] = entry;
}
} else {
// Add this to the known list and the filtered array
known.set(email, {
index: filtered.length,
expiryYear
});
filtered.push(entry);
}
}
console.log(filtered);
This has the advantage of not constantly re-scanning the new list for known entries.
You can filter out whole object based on unique key you want as below.
const obj =
[
{
"id": "1",
"name": "a",
"email": "abc#gmail.com",
"expiryType": "premium"
},
{
"id": "2",
"name": "b",
"email": "abc#gmail.com",
"expiryType": "gold"
},
{
"id": "3",
"name": "b",
"email": "test#gmail.com",
"expiryType": "premium"
}
]
function arrayUnique(arr, uniqueKey) {
const flagList = []
return arr.filter(function(item) {
if (flagList.findIndex(flagItem => flagItem[uniqueKey] === item[uniqueKey]) === -1) {
flagList.push(item)
return true
}
})
}
Method Calling....
let newObj = arrayUnique(obj,'email')
Output:
newObj = [
{
"id": "1",
"name": "a",
"email": "abc#gmail.com",
"expiryType": "premium"
},
{
"id": "3",
"name": "b",
"email": "test#gmail.com",
"expiryType": "premium"
}
]
Hope this helps.
You can do it simply with 2 loops. Maybe not the fastes but the simplest:
function deleteDouble(array, objectKey) {
for (var i = 0; i < array.length; i++) {
for (var j = 0; j < array.length; j++) {
if (i == j) {
continue;
}
if (array[i][objectKey] == array[j][objectKey]) {
array.splice(i, 1);
i = 0;
j = 0;
break;
}
}
}
return array;
}
deleteDouble(obj, "email");

Remove Multiple Objects from the group of Array

I would like to splice the whole Object inside the array "Docs > Exam" which has "Pass":"NO"
i have tried this
var docs = [
{"Id":1,"Name":"First","Exam":[{"Pass":"No"},{"Sub":"T1"}]},
{"Id":2,"Name":"Second","Exam":[{"Pass":"Yes"},{"Sub":"T2"}]},
{"Id":3,"Name":"Third","Exam":[{"Pass":"No"},{"Sub":"T3"}]}
];
for (var i = docs.length - 1; i >= 0; i--) {
for (var j = docs[i].Exam.length - 1; j >= 0; j--) {
if (docs[i].Exam[j].Pass == 'No') {
docs.splice(docs[i],1);
}
}
}
console.log(docs);
I need only the docs with this object only
{"Id":2,"Name":"Second","Exam":[{"Pass":"Yes"},{"Sub":"T2"}
This is very easy using filter and some:
docs = docs.filter(doc => doc.Exam.some(exam => exam.Pass === 'Yes'))
const isExamPassed = exam => exam.Pass === 'Yes';
1. docs.filter(doc => isExamPassed(doc.Exam[0]));
2. docs.map(doc => doc.Exam[0])
.filter(isExamPassed);
Use Array.filter API.
var docs = [{
"Id": 1,
"Name": "First",
"Exam": [{
"Pass": "No"
}, {
"Sub": "T1"
}]
},
{
"Id": 2,
"Name": "Second",
"Exam": [{
"Pass": "Yes"
}, {
"Sub": "T2"
}]
},
{
"Id": 3,
"Name": "Third",
"Exam": [{
"Pass": "No"
}, {
"Sub": "T3"
}]
}
];
console.log("Before Filtering: ", docs.length);
docs = docs.filter(function(doc, index) {
var bIsPass = true;
for (var j = doc.Exam.length - 1; j >= 0; --j) {
if (doc.Exam[j].Pass === "No") {
bIsPass = false;
break;
}
}
return bIsPass;
});
console.log("Before Filtering: ", docs.length);
console.log("Result :", docs);

Compare two objects in jQuery and get the difference [duplicate]

This question already has answers here:
How to get the difference between two arrays in JavaScript?
(84 answers)
Closed 7 years ago.
Using jQuery I would like to compare 2 objects:
sourceArray:
var origArray = [{
"Name": "Single",
"URL": "xxx",
"ID": 123
},
{
"Name": "Double",
"URL": "yyy",
"ID": 345
},
{
"Name": "Family",
"URL": "zzz",
"ID": 567
}];
destination array
var destArray = [{
"Name": "Single",
"URL": "xxx",
"ID": 123
},
{
"Name": "Double",
"URL": "yyy",
"ID": 888
},
{
"Name": "Family",
"URL": "zzz",
"ID": 567
}];
What I would like to do, is compare the target object with the source object based on the ID and find the mis-matched entries with a description on the resultant object. So the result will look like this:
var resultArray = [{
"Name": "Double",
"URL": "yyy",
"ID": 888,
"desc": "missing in source"
},
{
"Name": "Double",
"URL": "yyy",
"ID": 345,
"desc": "missing in destination"
}];
Any quick help is really appreciated.
This isn't a good use of jQuery, but here is some vanilla javascript that does what you want.
function objDiff(array1, array2) {
var resultArray = []
array2.forEach(function(destObj) {
var check = array1.some(function(origObj) {
if(origObj.ID == destObj.ID) return true
})
if(!check) {
destObj.desc = 'missing in source'
resultArray.push(destObj)
}
})
array1.forEach(function(origObj) {
var check = array2.some(function(destObj) {
if(origObj.ID == destObj.ID) return true
})
if(!check) {
origObj.desc = 'missing in destination'
resultArray.push(origObj)
}
})
return resultArray
}
https://jsfiddle.net/9gaxsLbz/1/
If you are wanting to dedupe your array, this will work:
var merged = origArray.concat(destArray);
var unique = merged.filter(function(item) {
return ~this.indexOf(item.ID) ? false : this.push(item.ID);
}, []);
Fiddle: https://jsfiddle.net/Ljzor9c6/
If you are only wanting items that were duped, you can easily invert the condition:
var merged = origArray.concat(destArray);
var dupes = merged.filter(function(item) {
return ~this.indexOf(item.ID) ? true : !this.push(item.ID);
}, []);
You can loop through the items in the first array and put the ID's in a map, then loop through the items in the second array and remove the matching ID's and add the missing.
Then just loop through the map to create the objects in the resulting array:
var origArray = [{
"Name": "Single",
"URL": "xxx",
"ID": 123
},
{
"Name": "Double",
"URL": "yyy",
"ID": 345
},
{
"Name": "Family",
"URL": "zzz",
"ID": 567
}];
var destArray = [{
"Name": "Single",
"URL": "xxx",
"ID": 123
},
{
"Name": "Double",
"URL": "yyy",
"ID": 888
},
{
"Name": "Family",
"URL": "zzz",
"ID": 567
}];
var map = {};
for (var i = 0; i < origArray.length; i++) {
map[origArray[i].ID] = 'source';
}
for (var i = 0; i < destArray.length; i++) {
var id = destArray[i].ID;
if (id in map) {
delete map[id];
} else {
map[id] = 'destination';
}
}
var resultArray = [];
for (key in map) {
var arr = map[key] == 'source' ? origArray : destArray;
for (var i = 0; arr[i].ID != key; i++) ;
resultArray.push({
Name: arr[i].Name,
URL: arr[i].URL,
ID: arr[i].ID,
desc: 'missing in ' + map[key]
});
}
// show result in StackOverflow snippet
document.write(JSON.stringify(resultArray));
var result = [];
for(var i = 0; i < oa.length; i++) {
var idx = mIndexOf(oa[i].ID);
if(idx > -1) {
oa.splice(i, 1);
da.splice(idx, 1);
}
}
for(var i = 0; i < oa.length; i++) {
var ln = result.length;
result[ln] = oa[i];
result[ln].desc = "missing in destination";
}
for(var i = 0; i < da.length; i++) {
var ln = result.length;
result[ln] = da[i];
result[ln].desc = "missing in origin";
}
function mIndexOf(id) {
for(var i = 0; i < oa.length; i++)
if(oa[i].ID == id)
return i;
return -1;
}
console.log(result);
0: Object
ID: 345
Name: "Double"
URL: "yyy"
desc: "missing in destination"
1: Object
ID: 888
Name: "Double"
URL: "yyy"
desc: "missing in origin"
jsfiddle DEMO
For things like this, you should use lodash. With lodash you can just do this:
var resultArray = _.defaults(destArray, origArray);

Javascript: How to get object from object in an array

Sample data:
{
"data": [
{
"name": {
"full": "JOHN",
"rank": "SENIOR"
},
"mobile": "12345"
},
{
"name": {
"full": "HENRY",
"rank": "SENIOR"
},
"mobile": "67890"
},
{
"name": {
"full": "SAM",
"rank": "JUNIOR"
},
"mobile": "54321"
}
]
}
i'm trying to get the total number of senior members from the data sample above, and i can get the data.name and data.mobile, but i can't get the 'rank' data from the parent 'name' object. can anyone please guide me to obtain the rank data. below is my javascript:
function countRank(rank) {
var i;
for (i in rank.data) {
if (rank.data[i] == "SENIOR") {
i++;
}
document.getElementById('senior').innerHTML = 'Total senior members: ' + i;
}
}
<div id="senior"></div>
Try this JSFIDDLE
function countRank(rank) {
var k=0;
for (var i=0; i< rank.data.length; i++) {
if (rank.data[i].name.rank == "SENIOR") {
k++;
}
document.getElementById('senior').innerHTML = 'Total senior members: ' + k;
}
}
countRank(rank);
You can make something like this
var rank = {
"data": [{
"name": {
"full": "JOHN",
"rank": "SENIOR"
},
"mobile": "12345"
}, {
"name": {
"full": "HENRY",
"rank": "SENIOR"
},
"mobile": "67890"
}, {
"name": {
"full": "SAM",
"rank": "JUNIOR"
},
"mobile": "54321"
}]
};
function countRank(rank) {
var i = 0,
arr = rank.data;
for (var j = 0; j < arr.length; j++) {
for (var prop in arr[j]) {
if (arr[j][prop].rank == "SENIOR") {
i++;
}
document.getElementById('senior').innerHTML = 'Total senior members: ' + i;
}
}
}
countRank(rank);
myObject.data[0].name.rank
>>> "SENIOR"
Assuming that whole object is called obj:
var i=0;
for (i=0; i < obj.data.length; i++) {
console.log(obj.data[i].name.rank);
}
function countRank(rank) {
var count = 0;
var arr = rank.data;
for (var i=0; i<arr.length; i++) {
var name = arr[i].name;
if (name.rank == "SENIOR") {
count++;
}
}
alert(count);
}
I checked it and it worked well.
Using jQuery you can find rank from above data easily.
checkout sample on jsFiddle
http://jsfiddle.net/uBnfu/
$.each(jsonData.data, function (index, value) {
alert(value.name['rank']);
});

Categories

Resources