How to compare two objects - javascript

I have a scenario, where I have two different Objects.
Scenario to achieve:
From two objects I need to match the values which has "A1","B2", etc...
Since both the objects values are not in proper order, the loop is breaking and missing some values.
In my demo the object1 has same repeated value i.e. "C3", It should be displayed only once.
Final output required is I need to detect only the matched values from two objects and display its corresponding "a" and "b values."
I have tried almost 90%, but somewhere some minor error is breaking my loop, Please help me out.
Sample code:
for(var i=0;i<obj1.results[0].loc.length;i++){
var findA = obj1.results[0].loc[i].anc[0].title;
for(var j=0;j< obj2.ILoc.length;j++){
var findB = obj2.ILoc[j].ais;
if(findA == findB) {
var a = obj1.results[0].loc[i].a;
var b = obj1.results[0].loc[i].b;
console.log(a);
console.log(b);
}
}
}
This is what I have tried:
Demo Link

I would recommend using for...in loop, since you're using objects instead of arrays.
for (variable in object) {...
}
If length property of both objects is equal, then this kind of loop alone will help you to compare objects with ease.

I would recommend using the diff module. You can use it in node.js and the browser.

Related

How do you iterate over a JavaScript object's properties like an array?

I don't mean using a for loop using the keys.
For example if you had an array like:
var fruitArray = ["Apples", "Bananas", "Coconuts"],
curFruit = 0;
You could "iterate" over that using buttons, say you've got a prev/next button and all those buttons do is decrement/increment the curFruit index.
So if I'm on Bananas, I could get Apples using the prev button using:
fruitArray[0] // Apples
Where the index was at 1 for Bananas but the prev button drops the index by one.
So with an unknown-length object, and not using a numbered-index, how could you do that?
Say it's like this:
var fruitObject = {"Apples":"Red", "Bananas":"Yellow", "Coconuts":"Brown"};
I realize you could have set 0, 1, 2 and the fruit name, but just to show that you don't know what the object key/index might be.
So if I'm on Bananas using
fruitObject.Bananas // yellow
How could I get to Apples using the same decrement idea as the Array?
My question is not about the for in method
I don't know why that's not clear, it was literally the first line in my question.
I think I found a solution anyway though it might not be direct/the most effective way to do it where I'll create a temporary local "look up".
To explain:
Here's an object
var colorObject = {"red":"apple", "blue":"blueberries", "yellow":"banana"};
I don't want to use the for in method to go from left to right complete.
I want to be able to start/keep a current position like I'm at "blue":"berries" and I can jump to "red":"apple" without knowing what "red":"apple" is
My current solution in mind is, yes, though ironically I would use the for in method but to create a look up array.
Something like
var tempArray = [];
for (var key in colorObject) {
tempArray.push(key);
}
Then I can navigate the object starting from anywhere using the increment/decrement method.
tempArray[1] would return "blue" and I could go to "red" by doing tempArray[0] which is interpreted as
colorObject.blue // blueberries
Edit thanks to the editor for making my question more clear
I did poorly word it so that's on me.
This is not possible. JavaScript object properties do not have a defined order, so there is no concept of Y key comes after X key.
Excerpt from EnumerateObjectProperties section of ECMAScript 2017 Draft (ECMA-262) (emphasis added):
The mechanics and order of enumerating the properties is not specified but must conform to the rules specified below.
If you were to iterate over the properties of your fruitObject object, "Bananas" may or may not come before "Coconuts", this behavior simply is not defined by the specification. There does not even appear to be a guarantee the properties will come back in the same order each time you iterate over the properties.
The only way to have a consistent order would be to have an array. Optionally, you could do this by creating an array of the properties via Object.keys.
var fruitObject = {"Apples":"Red", "Bananas":"Yellow", "Coconuts":"Brown"};
// Get the property keys in an ordered list:
var fruitObjectKeys = Object.keys(fruitObject);
// An array of properties with a consistent order:
fruitObjectKeys.forEach(function(prop) {
console.log(prop, '=', fruitObject[prop]);
});
Note however that the JavaScript engine running the code will decide what the order of the resulting array of properties is if you do it this way.
Objects don't have order, so you can't say that the first element of fruitObject is "Apples", the second is "Bananas" and the third is "Cocounts".
You could get the keys as an array with Object.keys() and then do something like
var keys=Object.keys(fruitObject);
fruitObject[keys[0]];
Remember that in JS it's the obj.key is the same than obj["key"].

Node.JS behaves strange

I have a variable called uids
var uids = [];
Then I write some value to it property
uids[16778923] = "3fd6335d-b0e4-4d77-b304-d30c651ed509"
But before it
if (!uids[user.id]) {
uids[user.id] = generateKey(user);
}
This thing behaves ok. If I try to get the value of it property
uids[currentUser.id]
It will give me a value of this property. If I try to call some methods like
Object.keys(uids);
It will give me, what I expected. And here the mystery comes...
uids;
RAM rest in piece. See the node eating ram
I am very confused now. What's wrong?
This is because you are creating a huge array and node will reserve memory for it - who knows what comes. I'd say that's a scenario where you would use a Map (or a plain object, but Map feels better here.
var uids = new Map();
var key = 456464564564654;
if (! uids.has(key)) {
uids.set(key, generateKey(user))
}
You are creating an empty array (length is zero), then you assign some value to an arbitrary index. This will make the array grow as big as the index and assign the value to that index. Look at this example using node.js REPL:
> var a = []
undefined
> a[5] = "something"
'something'
> a
[ , , , , , 'something' ]
> a.length
6
Instead of creating an array, you could create a Map() or an common javascript object (singleton). Javascript objects behave like Maps but only Strings can be used as keys. If you assign a Number to be key, javascript will convert it to String automatically.
Personally, I would go with objects because they perform better. Instantiating an object takes longer than instantiating a Map (and it doesn't seem like you need to create several groups of "uids"), but once done, adding new keys and retrieving values from any key in faster when using common objects. At least that's how things go in my node.js v6.7.0 on ubuntu 14.04 but you could try for yourself. And it would also make the least alteration to your code.
var uids = {} // common/ordinary empty javascript object instead of array.
if (!uids[user.id]) { // getting value from one key works the same.
uids[user.id] = generateKey(user) // assignment works the same.
}
////
uids[16778923] = "3fd6335d-b0e4-4d77-b304-d30c651ed509" // key will be "16778923".
uids[16778923] // getting value for key "16778923" can be done using 16778923 instead of "16778923".
////
uids[currentUser.id] // still returning values like this.
Object.keys(uids) // still returning an array of keys like this. but they are all Strings.

How to get all children of a subArray in Javascript

So here's my problem:
So this is what my array looks like, I have shown a fragment of it here (from the console window).
It's overall pretty basic right? Except for it's indexing. As you see the first has value "1" and let's say the second has value "4". As for it's subarrays, these have custom indexes too.
Therefore, the old fashioned:
for(i=0; i<array.length; i++){
someVar = array[i];
//do something
}
won't work.
I get the 1 or 4 from iterating through another array, so don't need to get those.
I want to get all subArrays(not the further nested subArrays, only the second level).
So basicly what I want is something like this(is there something like this?):
array[someIndex].children.forEach(
//do something with **this**
)
To make it more practical for you:
So I know that the first array has index 1. How can I get the values of cat1 and cat2 without knowing it has index 2 (this could also be 6 or 42 for example). In this case, the first array only has one subArray but I would like to make it work for multiple subArrays. (to clarify, select cat1, cat2 from the second level subarray with, in this case, index 2)
Thanks in advance, any help is appreciated!
Evoc
Those aren't arrays. You have
[ { "1": { etc...
which is an array containing an object containing multiple other objects. You can't really use a for(i=...) loop for this, because your keys aren't sequential. You should use a for ... in loop instead:
arr = [{"1":{....}}];
for (i in arr[0]) {
for (j in arr[0][i]) {
console.log(arr[0][i][j]['msg']);
}
}
Use Object.getOwnPropertyNames to get the properties ordered with the integer indices first, from smallest to greatest. Iterate them to get msg1.
var array = {"1":{"3":{"5":{"data":"someData","moreData":"someMoreData"},"msg1":"hello world","msg2":"foo equals bar"},"5":{"8":{"data":"someData","moreData":"someMoreData"},"msg1":"world hello","msg2":"bar equals foo"},"your_name":"jimmy","your_msg":"hello world"},"4":{"3":{"5":{"data":"someData","moreData":"someMoreData"},"msg1":"hello world","msg2":"foo equals bar"},"5":{"8":{"data":"someData","moreData":"someMoreData"},"msg1":"world hello","msg2":"bar equals foo"},"your_name":"billy","your_msg":"foo equals bar"}};
for(let key of Object.getOwnPropertyNames(array[1])) {
if(Object(array[1][key]) !== array[1][key]) break;
console.log('msg1 of "'+key+'": ' + array[1][key].msg1);
}
console.log('your_msg: ' + array[1].your_msg);
The example you showed it's an array with only one index, inside of this index there are nested objects, you could iterate them using the property iterator (foreach). You have to go to the second level tho, since the values you need are there.
for (var key in object) {
for(var anotherKey in object[key]) {
//check for undefined
if(object[key][anotherKey].hasOwnProperty('msg')) {
//code
}
}
}
{ } - declaring objects (literal)
[ ] - declaring arrays

Joining values in an Javascript array

Say I have:
var Certificated = {}
Sub items are added dynamically and variate. Possible outcome:
var Certificated = {
Elementary: ["foo","bar", "ball"]
MiddleSchool: ["bar", "crampapydime"]
};
I want to do the following:
Certificated.Elementary = Certificated.Elementary.join("");
Except I need it to do that on all of the objects inside.
Keep in mind I can't know for sure the titles of nor how many objects will be inside Certificated.
My question is how can I use .join("") on all elements inside Certificated, without calling each one specifically?
EDIT: I am aware .join() is for arrays and the objects inside Certificated are going to be arrays. Therefore the join method.
Does this work?
for (var key in Certificated) {
if (Certificated.hasOwnProperty(key)) {
Certificated[key] = Certificated[key].join("");
}
}
It loops through all properties of Certificated, and makes a quick safe check for the key being a real property, then uses bracket notation - [""] - to do your join.
Quick question - are you sure you want to use join? I know you just provided an example, but you can't call join on a string...it's for arrays. Just wanted to make sure you knew.
Here's a jsFiddle of my code working with arrays being used for the properties:
http://jsfiddle.net/v48dL/
Notice in the browser console, the properties' values are strings because the join combined them with "".

JavaScript array's length method

Can anyone explain why the second alert says 0 ?
var pollData = new Array();
pollData['pollType'] = 2;
alert(pollData['pollType']); // This prints 2
alert(pollData.length); // This prints 0 ??
The length of the array is only changed when you add numeric indexes. For example,
pollData["randomString"] = 23;
has no effect on length, but
var pollData = [];
pollData["45"] = "Hello";
pollData.length; // 46
changes the length to 46. Note that it doesn't matter if the key was a number or a string, as long as it is a numeric integer.
Besides, you are not supposed to use arrays in this manner. Consider it more of a side effect, since arrays are objects too, and in JavaScript any object can hold arbitrary keys as strings.
Because you haven't put anything into the array yet. You've only been assigning to a dynamically-created pollType attribute on the array object.
If you use numeric indices, then the array automagically takes care of length. For example:
var arr = [ ]; // same as new Array()
arr[2] = 'Banana!';
alert(arr.length); // prints 3 (indexes 0 through 2 were created)
The length property takes into consideration only those members of the array which names are indexes (like '1', '2', '3', ... ).
Arrays in JavaScript have numeric indexes only.
Use an object, which is essentially what you are doing above, setting properties on that array object.
array.length returns how many values are stored in the array. The first alert is returning the value of the position 'pollType'.
The reference guide I always use when needing help with javascript arrays is this page http://www.hunlock.com/blogs/Mastering_Javascript_Arrays
I'd also read what it says under the heading Javascript Does Not Support Associative Arrays, as you may run into problems with this also.
var pollData = Array();
function test() {
pollData[0] = 2
alert(pollData[0]);
alert(pollData.length);
}
//[x] is the array position; hence ['polltype'] is causing issues

Categories

Resources