Using the includes() function in this case [duplicate] - javascript

This question already has answers here:
Javascript: Using `.includes` to find if an array of objects contains a specific object
(7 answers)
Closed 24 days ago.
I got an array A and the console shows me:
Array [ Object, Object ].
When I click on one of the Object elements, the properties are shown on the console.
Now, I got a variable B which contains the first Object of my array A. I want to check this using the includes function:
A.includes(B)
However, it returns false. Is there something wrong with the use of includes()?

If I understand your question correctly, your setup looks like this:
const A = [ {hello: "world"}, {hi: "everyone"} ];
const B = {hello: "world"};
console.log(A.includes(B)); // returns false
A.includes(B) returns false because Javascript evaluates object equality based on objects' references (where they are stored in memory), not their values. As a result, even though B looks like it is included in A, the two objects have different references because they are declared independently of each other. You can read more about object equality in Javascript here: http://adripofjavascript.com/blog/drips/object-equality-in-javascript.html
Using this information, you can change your setup so you get the expected answer:
const A = [ {hello: "world"}, {hi: "everyone"} ];
const B = A[0];
console.log(A.includes(B)); // returns true

This works fine for me, but you might be getting hung up on the fact that includes works by strict equality. An object is not considered equal to another object with the same properties unless that other object is actually the same object. See the following example:
const b = {} //some object
const A = [b, 2]
console.log(A.includes(b)) //true
console.log([{}, 2].includes(b)) //false because {} !== b

Related

what is difference between using delete keyword , assign undefined value to object literal in javascript? [duplicate]

This question already has answers here:
delete a.x vs a.x = undefined
(9 answers)
Closed 10 months ago.
I met some needs for deep copying original object literals, excepts some keys.
I know spread operator doesn't copy deeply whole nested objects, however it's not main points for this question, so let's pass that issues.
so, back in original question,
I see no difference between using delete keyword and assign undefined to target property which I want to remove.
const original = {
a: 1,
b: 2,
}
const copied = {
...original,
b: undefined
}
const explicitDelete = {
...original
}
delete explicitDelete["b"]
seems copied way is less verbose, but it's totally okay with that way?
I see no difference between using delete keyword and assign undefined to target property
The difference is that the property still exists with the value undefined:
"b" in copied // true
"b" in explicitDelete // false
If you don't like the verbosity of delete, you can use a helper function
function omit(obj, ...keys) {
const res = {};
for (const p in obj)
if (!key.includes(p))
res[p] = obj[p];
return res;
}
omit(orignal, "b")
or object destructuring with rest syntax:
const {b:_, ...withoutB} = original;
See also How to omit specific properties from an object in JavaScript, How do I remove a property from a JavaScript object?, How can I clone a JavaScript object except for one key?.
There is definitely a difference. When you use delete, the object will no longer have the property name at all. The in operator will indicate that. Setting the property value to undefined will not have that effect.
delete removes the entry, that's the difference
let original = {a: 1, b: 2}
console.log("Original object:")
console.log(original)
original["a"] = undefined
console.log("After setting to undefined:")
console.log(original)
delete original["a"]
console.log("After actually deleting:")
console.log(original)
delete actually removes the key from the object, but setting it to undefined leaves the key, and just makes the key undefined. The difference is subtle, but it can become important in some cases.
It is a difference. with delta your will remove the key "b" completely from the object. However, when you assign undefined the key still be there and having undefined assigned.

Javascript Arrays - How do they work internally?

I wanted to know how javascript arrays work internally, I mean when for example you create a new array.
array = [1,2,3];
It's internally creating a new array: array = new Array();
and then calling Array.push() or similar?
Thanks.
The best resource to find out how javascript internals work is ECMAScript specification itself.
In order to understand what happens internally when you do array = [1, 2, 3] you would need to read section 7.3.16 CreateArrayFromList (elements). Roughly what happens is that first Array object gets created, then each element gets set to this object with CreateDataProperty (7.3.4 CreateDataProperty section) (DefineOwnProperty) internal method.
Then you want to learn what exactly happens when you push element to array. You check 22.1.3.17 Array.prototype.push ( ...items ) section for this. There you will find out that it uses quite different algorithm, namely it sets specific property of an object (7.3.3 Set (O, P, V, Throw) section).
So the answer is no, creating array like a = [1, 2, 3] does not uses same mechanics to insert items as push does. The first one roughly creates new property on (newly created) array object, the push sets property to existing object.
and then calling Array.push() or similar?
No. As you can see in the below example that when array is initialized push (overridden) method is not invoked.
Array.prototype.push = function(){ console.log("adding") };
var array = [1,2,3];
//console.log(array);
But, it is invoked when console statement is executed (after un-commenting the same).
var array = [1,2,3];
It doesn't call push but it's a simpler way to initialize an array when you know the elements in advance.
If you want to add another element you can do it in multiple ways like:
1) array.push(22); // adds integer 22 to the array
or
2) array[4] = 22; // adds integer 22 to the array at index 4
You can even do this:
array[20] = 22; // this will resize the array and keep all the uninitialized elements returns undefined. So array[10] is undefined, for ex.
If you want to know all the details about arrays explained in a simple way I recommend you the book: Secrets of the JavaScript Ninja. It has an entire chapter about arrays.
https://www.amazon.com/Secrets-JavaScript-Ninja-John-Resig/dp/1617292850/ref=sr_1_1?ie=UTF8&qid=1519484868&sr=8-1&keywords=javascript+ninja

Concept: Comparing objects and arrays like atrings and numbers in JavaScript [duplicate]

This question already has answers here:
Object comparison in JavaScript [duplicate]
(10 answers)
Closed 5 years ago.
Is there a way to compare two un-referenced objects by their literal value like a string or a number?
_is = function (a, b) { /* Code */ }
This could apply to any object type, even custom objects.
_is(new X("a"), new X("a")); // Returns True;
_is(new X("a"), new Y("a")); // Returns False
You could convert it into a string, but that would be sloppy.
JSON.stringify({ x: "a" }) == JSON.stringify({ x: "a" }); // Returns True
Maybe there's a way to programatically read each key, subkey, and value of the object, and compare that way.
Any ideas?
Javascript hashes objects in memory with unique memory pointers. You're essentially creating two separate objects, and trying to compare them. Despite the fact that they look similar, they in fact are different.
Try storing the object as a variable first, and then testing against that variable.
pass = arg => { return arg }; pass({ a: "x" }); // Returns The Input
pass(({ a: "x" })) == ({ a: "x" }); // Returns False
var obj = {a: "x"};
pass(obj) === (obj); // Returns true
console.log(pass(obj) === (obj));
UPDATE:
If you want to compare two separate objects, the best and most efficient way I've found is to create a hash of both objects, and then compare the hashes (basically comparing two checksums). If the hashes match, the objects are the same. If the hashes differ, they are different objects. You can assume that the properties and values are the same in each object, since using a hashing function, even hashing functions used in some forms of crypto like md5 and sha can be utilized to generate a unique hash of the object.
Here's a 3rd Party Library I've used before to generate object hashes.

JS Array a['1'] doesnot gives an error

I have declared an array a = [1,2,3,4,5]
When I write a[1] it returns 2 which is perfectly fine but when I write a['1'] it also gives me 2 instead of giving an error.
I was expecting an error there. Why does it behave like that??
All property names are strings.
If you pass a number, it gets converted to a string before being used to look up the property value.
console.log(1 == '1');
In JS an Array is basically an Object and thus mostly behaves like one. In this case, these are equivalent as long as you dont access Array's .length or try iterating a:
const a = {"0": foo};
const b = ["foo"];
Also this would work:
const a = ["foo"];
a.bar = "baz";
console.log(a);
So that a[1] and a['1'] are equivalent is exactly what's to be expected.
First of all, array is also object having property names as 0,1,2,....n
Property names must be strings. This means that non-string objects cannot be used as keys in the object. Any non-string object, including a number, is typecasted into a string via the toString method. [Ref]

array.indexOf in TypeScript/JavaScript [duplicate]

This question already has answers here:
indexOf method in an object array?
(29 answers)
Closed 7 years ago.
UPDATE: Although this question is marked as duplicated with this. But #ssube's way is neat and much smarter.
UPDATE2: Seems there is new way to do it in the comment by #Grungondola.
I am using Typescript.
This works well.
var array1 = [];
array1.push(5);
array1.push(6);
console.log("a", array2.indexOf(6));
But this does not work well. Because array2.indexOf returns -1 which means it does not find it.
var array2 = [];
array2.push({aa:5,bb:5});
array2.push({aa:6,bb:6});
console.log(array2.indexOf({aa:6,bb:6}));
Looks like indexOf does not support Object. Does TypeScript have its own ways to deal with this kind of problem? Thanks.
No. The problem is not with Object, but that you are creating two different objects.
The object literal syntax ({foo: 'bar'}) declares an object inline. When the script is executed, the object is created. Using that syntax multiple times creates multiple objects.
You can easily test that with {foo: 3} === {foo: 3}. This will evaluate to false, but they are not the same object (reference).
The indexOf method checks if the object, string, number, etc, is present in the array. You're passing a new object, which is not in the array.
If you have a reference to the object, you can use that and indexOf will work:
var foo = {aa:5,bb:5}, bar = {aa:6,bb:6};
var array2 = [];
array2.push(foo);
array2.push(bar);
console.log(array2.indexOf(foo));
Because you're referring to the same instance, this will print the index.
You can also use filter or find with a predicate to perform a deep search:
function deepIndexOf(arr, obj) {
return arr.findIndex(function (cur) {
return Object.keys(obj).every(function (key) {
return obj[key] === cur[key];
});
});
}
var array2 = [];
array2.push(foo);
array2.push(bar);
console.log(deepIndexOf(array2, foo));
This won't recurse into nested objects, but will accomplish the comparison you're looking for (equivalence on two objects and their immediate fields).

Categories

Resources