How to Combine or Merge Object Array with Object Array Jquery - javascript

i have an object like this in my console:
ObjectName1 : Array(3)
0 : { id : 1, name : 'foo' },
1 : { id : 2, name : 'foo-2' },
2 : { id : 3, name : 'foo-3' },
ObjectName2 : Array(3)
0 : { id : 1, foo : 'bar' },
1 : { id : 2, foo-2 : 'bar-2' },
2 : { id : 3, foo-3 : 'bar-3' },
and as usually if we want to get the name, just write : ObjectName1[key].name right ?
now if i want to get the key from ObjectName2 (foo, foo-2, foo-3) how to get the key from ObjectName2 using the value from ObjectName1 ?
i have written like this :
// just say there is an each above this comment
var name = ObjectName1[key].name;
var bar = ObjectName2[key]+"."+name;
// end each
but it just showed
[Object object].foo
[Object object].foo-2
[Object object].foo-3
the output should be like this :
bar
bar-2
bar-3
it is possible doing like i want to do ? help me please if it is possible
any help will be very appreciated.
*note : i'm not sure what is the case name in my problem, so forgive me if the title went wrong
thanks

Try this one. Loop through each object in ObjectName1 object and get the name in appropriate index, this name will be the key for the ObjectName2 object. Then use that key to print the appropriate value from ObjectName2
var ObjectName1 = [{'id' : 1, 'name' : 'foo'}, {'id' : 2, 'name' : 'foo-2'}, {'id' : 3, 'name' : 'foo-3'}];
var ObjectName2 = [{'id' : 1, 'foo' : 'bar'}, {'id' : 2, 'foo-2' : 'bar-2'}, {'id' : 3, 'foo-3' : 'bar-3'}];
for(var i = 0; i < ObjectName2.length; i++){
console.log(ObjectName2[i][ObjectName1[i]['name']]);
}

Something like this?
var name = ObjectName1[key].name;
ObjectName2.forEach(function(a) {
if (a.keys().includes(name)) {
var bar = a[name];
// then do what you want with bar
}
}

As commented, your key is an object. Hence, it is showing [Object object].foo-3.
You will have to use 2 loops and check if the key is inside current object. If yes, print it, else continue.
var ObjectName1 =[
{ id : 1, name : 'foo' },
{ id : 2, name : 'foo-2' },
{ id : 3, name : 'foo-3' },
]
var ObjectName2 = [
{ id : 1, foo : 'bar' },
{ id : 2, 'foo-2' : 'bar-2' },
{ id : 3, 'foo-3' : 'bar-3' },
];
ObjectName1.forEach(function(obj){
ObjectName2.forEach(function(obj2){
var key = obj.name;
if(key in obj2){
console.log(obj2[key])
}
})
})

now if i want to get the key from ObjectName2 (foo, foo-2, foo-3) how to get the key from ObjectName2 using the value from ObjectName1 ?
If you know those are parallel arrays (where [0] in one array is intentionally a match for [0] in the other array), you can simply loop through:
ObjectName1.forEach(function(entry1, index) {
var value = ObjectName2[index][entry1.name];
console.log(entry1.name + " = " + value);
});
Example:
var ObjectName1 = [
{ id : 1, name : 'foo' },
{ id : 2, name : 'foo-2' },
{ id : 3, name : 'foo-3' }
];
var ObjectName2 = [
{ id : 1, "foo" : 'bar' },
{ id : 2, "foo-2" : 'bar-2' },
{ id : 3, "foo-3" : 'bar-3' }
];
ObjectName1.forEach(function(entry1, index) {
var value = ObjectName2[index][entry1.name];
console.log(entry1.name + " = " + value);
});
That assumes you know they're parallel arrays.
If not, you have to search for it. Array.prototype.findIndex will return the index of the first element where a callback returns true:
ObjectName1.forEach(function(entry1) {
console.log("entry1.name = " + entry1.name);
var index = ObjectName2.findIndex(function(entry2) {
// See if entry2 contains a key with that value
return entry1.name in entry2;
});
console.log(index == -1 ? "Not found" : ("Found at index #" + index + ", value = " + ObjectName2[index][entry1.name]));
});
Example:
var ObjectName1 = [
{ id : 1, name : 'foo' },
{ id : 2, name : 'foo-2' },
{ id : 3, name : 'foo-3' }
];
var ObjectName2 = [
{ id : 1, "foo" : 'bar' },
{ id : 2, "foo-2" : 'bar-2' },
{ id : 3, "foo-3" : 'bar-3' }
];
ObjectName1.forEach(function(entry1) {
console.log("entry1.name = " + entry1.name);
var index = ObjectName2.findIndex(function(entry2) {
// See if entry2 contains a key with that value
return entry1.name in entry2;
});
console.log(index == -1 ? "Not found" : ("Found at index #" + index + ", value = " + ObjectName2[index][entry1.name]));
});
If you don't really need the key (e.g., index) of the matching object in ObjectName2, just the object, use find instead:
ObjectName1.forEach(function(entry1) {
console.log("entry1.name = " + entry1.name);
var entry = ObjectName2.find(function(entry2) {
// See if entry2 contains a key with that value
return entry1.name in entry2;
});
console.log(!entry ? "Not found" : ("Found, value is " + entry[entry1.name]));
});
Example:
var ObjectName1 = [
{ id : 1, name : 'foo' },
{ id : 2, name : 'foo-2' },
{ id : 3, name : 'foo-3' }
];
var ObjectName2 = [
{ id : 1, "foo" : 'bar' },
{ id : 2, "foo-2" : 'bar-2' },
{ id : 3, "foo-3" : 'bar-3' }
];
ObjectName1.forEach(function(entry1) {
console.log("entry1.name = " + entry1.name);
var entry = ObjectName2.find(function(entry2) {
// See if entry2 contains a key with that value
return entry1.name in entry2;
});
console.log(!entry ? "Not found" : ("Found, value is " + entry[entry1.name]));
});

Related

How can I remove duplicates in an array of object?

I have an array which looks like this :
var array =
[
{
key : { id : 1 , pack : "pack 1"},
values : [
{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : {id : 2 , name : "itemP12"}
},
]
}
]
I want to remove duplicate itemP so with a function it will look like this :
var array =
[
{
key : { id : 1 , pack : "pack 1"},
values : [
{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : null
},
]
}
]
When I try I always have errors. It is possible to do this?
Update
I try to do this :
console.log(array.map(pack =>
pack.values.map((item) => {
var test = JSON.stringify(item)
var set = new Set(test)
return Array.from(set).map((item)=> JSON.parse(item))
}
)
))
Unexpected end of JSON input
I also try something will filter but it doesn't work:
console.log(this.package.map(pack => pack.values.filter(
(value, index , array) => array.itemP.indexOf(value) === index
)))
Instead of mapping every key property, I suggest cloning the whole structure and setting the object value as null in the cloned one, avoiding unintentionally mutating the original structure.
function nullifyDupes(array) {
const clone = JSON.parse(JSON.stringify(array));
const seen = {};
clone.forEach(pack => {
pack.values.forEach(items => {
for (const item in items) {
const id = items[item].id;
if (seen[id]) items[item] = null;
else seen[id] = true;
}
});
});
return clone;
}
const originalArray = [{
key : { id : 1 , pack : "pack 1"},
values : [{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : {id : 2 , name : "itemP12"}
}]
}];
const mutatedArray = nullifyDupes(originalArray);
console.log(mutatedArray);
To achieve expected result, use below option of using map
Loop array using map
Use nameArr to check duplicate and assigning null value
Loop values array and check the name in nameArr using indexOf and assign null
var array = [
{
key : { id : 1 , pack : "pack 1"},
values : [
{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : {id : 2 , name : "itemP12"}
}
]
}
]
console.log(array.map(v => {
let nameArr = []
v.values = v.values.map(val => {
if(nameArr.indexOf(val.itemP.name) !== -1){
val.itemP.name = null
}else{
nameArr.push(val.itemP.name)
}
return val
})
return v
}))
You can use map and an object to check if its already exist. Like
var obj = {}
and loop over values
var values = [
{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : {id : 2 , name : "itemP12"}
}
]
values.map((v) => {
if(!obj[v.itemP.id + '-' + v.itemP.name]) {
obj[v.itemP.id + '-' + v.itemP.name] = true;
return v;
}
return { item : v.item }
})
You can map your array elements to array objects which don't include your duplicates using .map(). For each iteration of .map() you can again use .map() for your inner values array to convert it into an array of objects such that the duplicates are converted to null. Here I have kept a seen object which keeps track of the properties seen and their stringified values. By looping over all the properties in your object (using for...of), you can work out whether or not the key-value pair has been seen before by using the seen object.
The advantage of this approach is that it doesn't just work with one property (ie not just itemP), but it will work with any other duplicating key-value pairs.
See example below:
const array = [{key:{id:1,pack:"pack 1"},values:[{item:{id:1,name:"item1"},itemP:{id:2,name:"itemP12"}},{item:{id:4,name:"item4"},itemP:{id:2,name:"itemP12"}}]}];
const seen = {};
const res = array.map(obj => {
obj.values = obj.values.map(vobj => {
for (let p in vobj) {
vobj[p] = seen[p] === JSON.stringify(vobj[p]) ? null : vobj[p];
seen[p] = seen[p] || JSON.stringify(vobj[p]);
}
return vobj;
});
return obj;
});
console.log(res);
For an approach which just removed itemP from all object in accross your array you can use:
const array = [{key:{id:1,pack:"pack 1"},values:[{item:{id:1,name:"item1"},itemP:{id:2,name:"itemP12"}},{item:{id:4,name:"item4"},itemP:{id:2,name:"itemP12"}}]}];
let itemP = "";
const res = array.map(obj => {
obj.values = obj.values.map(vobj => {
vobj.itemP = itemP ? null : vobj.itemP;
if('itemP' in vobj) {
itemP = itemP || JSON.stringify(vobj.itemP);
}
return vobj;
});
return obj;
});
console.log(res);

Firebase functions getChild value

I am having a problem on firebase functions. What I trying to do is when Items's child gets updated, then I want to get the value of Count and do further calculation, But what I am facing is that the firebase log console always shows an erreor "TypeError: Cannot read property 'val' of undefined".
JSON structure
"VTEST" : {
"A" : {
"Count" : 5,
"Items" : {
"item1" : "apple"
},
"NUMBER" : 5
},
"B" : {
"Count" : 8,
"Items" : {
"item1" : "orange;"
},
"NUMBER" : 3
},
"C" : {
"Count" : 10,
"Items" : {
"item1" : "grape"
},
"NUMBER" : 7
},
"D" : {
"Count" : 12,
"Items" : {
"item1" : "grava"
},
"NUMBER" : 10
},
"E" : {
"Count" : 15,
"Items" : {
"item1" : "fish"
},
"NUMBER" : 12
},
"F" : {
"Count" : 18,
"Items" : {
"item1" : "chicken;"
},
"NUMBER" : 8
}
}
My code:
exports.ItemCount = functions.database.ref('/VTEST/{ID}/Items').onUpdate((updateRef, context) => {
var childCount = updateRef.after.numChildren();
var newReference = updateRef.after.ref.parent.child('/Count');
var Count = newReference.val();
Count = Count + childCount;
return updateRef.ref.update({Count})
})
What I expect is the Count's value will be update, but it always show error : "TypeError: Cannot read property 'val' of undefined"
Can anyone tell me what am I doing wrong here, I don't get it.
The problem comes from the fact that a Reference does not have a val() method. You need to use the once() method to get the value of the corresponding database location.
The following adapted code should work:
exports.ItemCount = functions.database
.ref('/VTEST/{ID}/Items')
.onUpdate((updateRef, context) => {
var childCount = updateRef.after.numChildren();
var newReference = updateRef.after.ref.parent.child('/Count');
return newReference.once('value').then(dataSnapshot => {
var Count = dataSnapshot.val();
Count = Count + childCount;
return newReference.parent.update({ Count: Count });
});
});
However, depending on your exact requirements, you may decide to use a Transaction, see https://firebase.google.com/docs/database/web/read-and-write#save_data_as_transactions

I don't know how to implementate the function reduce

I do not know how to implement the reduce function.
I have output from my map a document as ...
for example two documents
key "_id":"AD"
"values"
{
"numtweets" : 1,
"hastags" : {
"OPINIÓ" : 1,
"debat" : 1,
"inexistent" : 1,
"tampoc" : 1,
"promet" : 1,
"gaire" : 1,
"diàleg" : 1
}
}
and other
{
"numtweets" : 1,
"hastags" : {
"other" : 1,
"debat" : 1,
"inexistent" : 1,
"another" : 1,
}
}
I need a function that reduces all sum so that
"numtweets" : 2,
"dicwords" : {
"OPINIÓ" : 1,
"debat" : 2,
"inexistent" : 2,
"tampoc" : 1,
"promet" : 1,
"gaire" : 1,
"diàleg" : 1,
"other" : 1,
"another" : 1
},
"lisuser" : {
"user2" : 1
}
if my json values was only nuwtweets the reduce is
function(key, values) {
return Array.sum(values);
};
if mi json values only was hastags (without numtweets and lisuser) the reduce function was
var r = function(key, values) {
result = {}
values.forEach(function(val) {
for (hashtag in val) {
if (hashtag in result) {
result[hashtag] = result[hashtag] + val[hashtag]
} else {
result[hashtag] = val[hashtag]
}
}
});
return(result)
};
But I don't know how mix the 2 reduce function.
My level of mongodb and JavaScript is very low.
Thanks
Try this:
let data = values.reduce((finalObj, ele) => {
finalObj.numtweets += ele.numtweets
for (key in ele.hastags) {
if(ele.hastags.hasOwnProperty(key)) {
if(finalObj.hastags[key])
finalObj.hastags[key] += ele.hastags[key]
else
finalObj.hastags[key] = ele.hastags[key]
}
}
return finalObj
})
console.log(data)
Where values is array for objects which you want reduce to one object

JavaScript - Insert & Remove a element in object

I have a object.
var dl_items;
After a loop for inputing data:
dl_items[code] = itemObject;
I have a array:
dl_items : {
"code_A" : { "index" : 1, "status" : 2, "name" : A_data},
"code_B" : { "index" : 2, "status" : 0, "name" : B_data},
"code_C" : { "index" : 3, "status" : 1, "name" : C_data},
"code_D" : { "index" : 4, "status" : 2, "name" : D_data},
"code_E" : { "index" : 5, "status" : 4, "name" : E_data}
}
Now I want to remove "dl_items[code_D]" and insert it into after "code_A" (index 2) for result like :
dl_items : {
"code_A" : { "index" : 1, "status" : 2, "name" : A_data},
"code_D" : { "index" : 4, "status" : 2, "name" : D_data},
"code_B" : { "index" : 2, "status" : 0, "name" : B_data},
"code_C" : { "index" : 3, "status" : 1, "name" : C_data},
"code_E" : { "index" : 5, "status" : 4, "name" : E_data}
}
I try to use "delete" after using a loop to find index of code_D:
delete dl_items[code_D];
and it successful removed but how can i insert code_D into his new index ?
Edit : Thanks all everyone to help me understand more about array.
Since object doesn't have an order, you need to convert your current implementation into array:
var dl_items = [];
When you need to add an item to the array:
dl_items.push({ code: code, item: itemObject });
Now, the similar data as array from your question is:
dl_items: [
{ code :"code_A", item: { index: 1, status: 2, name: "A_data" } },
{ code :"code_B", item: { index: 2, status: 0, name: "B_data" } },
{ code :"code_C", item: { index: 3, status: 1, name: "C_data" } },
{ code :"code_D", item: { index: 4, status: 2, name: "D_data" } },
{ code :"code_E", item: { index: 5, status: 3, name: "E_data" } },
]
In order to move the entry with code_D after the entry with code_A, use the following:
var codeDEntry = dl_items[3];
dl_items = dl_items
.filter(function(entry) {
return entry !== codeDEntry;
})
.splice(1, 0, codeDEntry);
Hope this helps!
You can make a temp var like this :
tempItem = dl_items.code_D;
dl_items.code_D = dl_items.code_B;
dl_items.code_B = tempItem;
What you have here is an object, not an array. Therefore, there is no concept of an index here.
You can map your object keys into an array as follows:
let array = Object.keys(dl_items);
You can then reorder their positions.

scope in javascript.. parent scope variable not retaining value

I am a newbie to javascript..have gone thru multiple scope related blogs and several answers on stackoverflow..but not sure why this code doesnt work..
function checkPhoneEmail(element, index, array) {
var _contact = {};
var _phone_empty = true;
var _email_empty = true;
var _phones_to_store = [];
var _emails_to_store = [];
var _prev_phone_number;
var _phone;
var i;
//function to check if this phone
// should be included
function checkMobilePhone(ph_element) {
var _match;
_match = ph_element.type.match(/mobile/i);
if (_match && ph_element.value.length >= 10 && !(ph_element.value.match(/^800/) || ph_element.value.match(/^1800/) || ph_element.value.match(/^1-800/))) {
return true;
};
return false;
};
if (!_.isEmpty(element.phoneNumbers)) {
for (i = 0; i < element.phoneNumbers.length; i++) {
console.log('prev num: ' + _prev_phone_number);
console.log('curr num: ' + element.phoneNumbers[i].value)
if (!_.isEqual(_prev_phone_number, element.phoneNumbers[i].value)) {
if (checkMobilePhone(element.phoneNumbers[i])) {
_phone = {
id: element.phoneNumbers[i].id,
value: element.phoneNumbers[i].value
};
_phones_to_store.push(_phone);
console.log('phone to store: ' + element.phoneNumbers[i].value)
};
};
_prev_phone_number = element.phoneNumbers[i].value;
console.log('prev1 num: ' + _prev_phone_number);
};
_phone_empty = false;
};
if (!_.isEmpty(element.emails)) {
};
};
why is the _prev_phone_number not being set ? I see it at prev1 num..but when you look for the next element its set back to undefined...my understanding is for doesnt create a new scope ? is this incorrect ?
I am trying to remove duplicates from phone contacts array (from cordova contacts) and doing some very basic checks to eliminate all numbers except a valid us mobile # for a mobile app..using above logic if a contact has multiple entries in contacts for same phone number i am seeing duplicates..Tried above logic with foreach and also _.uniq ... but same result..
Any help is appreciated.
sample Data:
{
"id" : "1916",
"rawId" : "1911",
"displayName" : "John Doe",
"name" : {
"familyName" : "Doe",
"formatted" : "John Doe",
"givenName" : "John"
},
"nickname" : null,
"phoneNumbers" : [{
"type" : "mobile",
"value" : "+1 999 666 9175",
"id" : "11994",
"pref" : false
}, {
"type" : "mobile",
"value" : "+1 999 666 9175",
"id" : "12001",
"pref" : false
}
],
"emails" : null,
"addresses" : null,
"ims" : null,
"organizations" : null,
"birthday" : null,
"note" : "",
"photos" : null,
"categories" : null,
"urls" : null
}
Instead of using the variable _prev_phone_number, why don't you just access element.phoneNumbers[i-1].value? No need to introduce a new variable for it.
If that doesn't work, then something is clobbering your object and we will need to look deeper.
A for loop does not create its own scope. The issue is that you are trying to log to the console an undefined value.
for (i = 0; i < element.phoneNumbers.length; i++) {
//_prev_phone_number is undefined here.
console.log('prev num: ' + _prev_phone_number);
console.log('curr num: ' + element.phoneNumbers[i].value)
if (!_.isEqual(_prev_phone_number, element.phoneNumbers[i].value)) {
if (checkMobilePhone(element.phoneNumbers[i])) {
_phone = {
id: element.phoneNumbers[i].id,
value: element.phoneNumbers[i].value
};
_phones_to_store.push(_phone);
console.log('phone to store: ' + element.phoneNumbers[i].value)
};
};
//This is the first time you have defined _prev_phone_number
_prev_phone_number = element.phoneNumbers[i].value;
console.log('prev1 num: ' + _prev_phone_number);
};
You should probably check to see if _prev_phone_number has been defined before logging it to the console.
if(_prev_phone_number){
console.log('prev num: ' + _prev_phone_number);
}
This would ensure that you are not logging an undefined value.

Categories