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).
Related
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
This question already has answers here:
How do I persist a ES6 Map in localstorage (or elsewhere)?
(10 answers)
Convert ES6 Class with Symbols to JSON
(6 answers)
Is there a way of specifying what data of an object is passed to the serializer when it's being serialized?
(2 answers)
Closed 5 years ago.
I am developing an Angular app. I use Typescript and have a certain class which contains the built-in Set and a Map types. My problem is that I want to store instances of my class in the browser's localStorage as JSON, but when I try to stringify them I get empty strings for these types.
Example from chrom's console:
> inst = new Object({
'elem': new Set(),
'str': 'somestring'
})
: Object {elem: Set(0), str: "somestring"}elem: Set(0)str: "somestring"}
> inst.elem.add('123');
: Set(1) {"123"}
> inst.elem.add('123');
: Set(1) {"123"}size: (...)__proto__: Set[[Entries]]: Array(1)0: "123"length: 1
> JSON.stringify(inst)
: "{"elem":{},"str":"somestring"}"
The only thing I could think of is recursively converting Sets and Maps to Arrays and Objects respectively before stringifying. But it sounds like much effort.
Is there a better way? Thanks.
Converting a Map to a simple Object won't work, unless the keys happen to be all strings. Remember that Maps can have anything as keys, including things that are not equal by reference but that will result in the same string when coerced.
The obvious way to serialise Maps and Sets would be, indeed, to convert them to arrays and then serialise that. Fortunately, you don't have to write much code yourself, just use the built-in iterators:
const map = new Map([['a', 1], ['b', 2]])
const set = new Set([2,3,5,7,11])
serializedMap = JSON.stringify([...map]) // => [["a", 1], ["b", 2]]
serializedSet = JSON.stringify([...set]) // => [2,3,5,7,11]
Now, as you noticed, you'll have some trouble with nested Maps and Sets. To avoid writing specific code to dive into objects and turn their deeply nested Map and Set values into arrays, you can define the toJSON method on Map and Set prototypes. The method is called implicitly by JSON.stringify:
Map.prototype.toJSON = function () {
return [...this]
}
// or, if you really want to use objects:
Map.prototype.toJSON = function () {
var obj = {}
for(let [key, value] of this)
obj[key] = value
return obj
}
// and for Sets:
Set.prototype.toJSON = function () {
return [...this]
}
Be careful, toJSON may be defined for Sets and Maps sometime in the future, with a different behaviour than this. Although it seems unlikely.
Now, whenever you call JSON.stringify and it sees a Map or Set, it will notice the toJSON method and use it instead of just copying the object's properties.
Another, similar and more ECMA-approved solution is to use JSON.stringify's second argument. Define a helper function that will preprocess values, replacing Maps and Sets with appropriate arrays or objects:
function mapReplacer(key, value) {
if(value instanceof Map || value instanceof Set) {
return [...value]
// of course you can separate cases to turn Maps into objects
}
return value
}
Now just pass mapReplacer to JSON.stringify:
JSON.stringify(map, mapReplacer)
What’s the difference between “{}” and “[]” while declaring a JavaScript array?
Normally I declare like
var a=[];
What is the meaning of declaring the array as var a={}
Nobody seems to be explaining the difference between an array and an object.
[] is declaring an array.
{} is declaring an object.
An array has all the features of an object with additional features (you can think of an array like a sub-class of an object) where additional methods and capabilities are added in the Array sub-class. In fact, typeof [] === "object" to further show you that an array is an object.
The additional features consist of a magic .length property that keeps track of the number of items in the array and a whole slew of methods for operating on the array such as .push(), .pop(), .slice(), .splice(), etc... You can see a list of array methods here.
An object gives you the ability to associate a property name with a value as in:
var x = {};
x.foo = 3;
x["whatever"] = 10;
console.log(x.foo); // shows 3
console.log(x.whatever); // shows 10
Object properties can be accessed either via the x.foo syntax or via the array-like syntax x["foo"]. The advantage of the latter syntax is that you can use a variable as the property name like x[myvar] and using the latter syntax, you can use property names that contain characters that Javascript won't allow in the x.foo syntax.
A property name can be any string value.
An array is an object so it has all the same capabilities of an object plus a bunch of additional features for managing an ordered, sequential list of numbered indexes starting from 0 and going up to some length. Arrays are typically used for an ordered list of items that are accessed by numerical index. And, because the array is ordered, there are lots of useful features to manage the order of the list .sort() or to add or remove things from the list.
When you declare
var a=[];
you are declaring a empty array.
But when you are declaring
var a={};
you are declaring a Object .
Although Array is also Object in Javascript but it is numeric key paired values.
Which have all the functionality of object but Added some few method of Array like Push,Splice,Length and so on.
So if you want Some values where you need to use numeric keys use Array.
else use object.
you can Create object like:
var a={name:"abc",age:"14"};
And can access values like
console.log(a.name);
var a = [];
it is use for brackets for an array of simple values.
eg.
var name=["a","b","c"]
var a={}
is use for value arrays and objects/properties also.
eg.
var programmer = { 'name':'special', 'url':'www.google.com'}
It can be understood like this:
var a= []; //creates a new empty array
var a= {}; //creates a new empty object
You can also understand that
var a = {}; is equivalent to var a= new Object();
Note:
You can use Arrays when you are bothered about the order of elements(of same type) in your collection else you can use objects. In objects the order is not guaranteed.
they are two different things..
[] is declaring an Array:
given, a list of elements held by numeric index.
{} is declaring a new object:
given, an object with fields with Names and type+value,
some like to think of it as "Associative Array".
but are not arrays, in their representation.
You can read more # This Article
Syntax of JSON
object = {} | { members }
members = pair | pair, members
pair = string : value
array = [] | [ elements ]
elements = value | value elements
value =
string|number|object|array|true|false|null
In JavaScript Arrays and Objects are actually very similar, although on the outside they can look a bit different.
For an array:
var array = [];
array[0] = "hello";
array[1] = 5498;
array[536] = new Date();
As you can see arrays in JavaScript can be sparse (valid indicies don't have to be consecutive) and they can contain any type of variable! That's pretty convenient.
But as we all know JavaScript is strange, so here are some weird bits:
array["0"] === "hello"; // This is true
array["hi"]; // undefined
array["hi"] = "weird"; // works but does not save any data to array
array["hi"]; // still undefined!
This is because everything in JavaScript is an Object (which is why you can also create an array using new Array()). As a result every index in an array is turned into a string and then stored in an object, so an array is just an object that doesn't allow anyone to store anything with a key that isn't a positive integer.
So what are Objects?
Objects in JavaScript are just like arrays but the "index" can be any string.
var object = {};
object[0] = "hello"; // OK
object["hi"] = "not weird"; // OK
You can even opt to not use the square brackets when working with objects!
console.log(object.hi); // Prints 'not weird'
object.hi = "overwriting 'not weird'";
You can go even further and define objects like so:
var newObject = {
a: 2,
};
newObject.a === 2; // true
[ ] - this is used whenever we are declaring an empty array,
{ } - this is used whenever we declare an empty object
typeof([ ]) //object
typeof({ }) //object
but if your run
[ ].constructor.name //Array
so from this, you will understand it is an array here Array is the name of the base class.
The JavaScript Array class is a global object that is used in the construction of arrays which are high-level, list-like objects.
I notice a difference when I declare a variable as an array or object and then add elements to it.
When I declare my variable as below:
var my_array = [];
my_array["a"] = 'first';
my_array["b"] = 'second';
console.log(my_array);
I get the following result:
[a: "first", b: "second"]
However, when I do the following:
var my_array = {};
my_array["a"] = 'first';
my_array["b"] = 'second';
console.log(my_array);
This is the result I get:
Object {a: "first", b: "second"}
What is really going on here?! Is one way standard, and the other not?! What are the downsides with compatibility?!
Thanks in advance.
P.S. I'm using Google Chrome.
The first is an array and the secound is an object, which one to use depands on your goal, if you need arrays the array will be more usefull and effiecent than using an "array" object.
Further more an object can be used like this:
myObject.a
While an array can be only used like this: myArray["a"]
Another diffrence is in the toString method. For an array it returns Banana,Orange,Apple,Mango (for example) and for an object it returns [object Object](for example).
For further reading: What is the difference between an array and an object?
Check if is array:
function isArray(obj) {
return Object.prototype.toString.call(obj) === "[object Array]";
}
They are two different objects.
I use the second for JSON response, and the first for normal use in the code.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
JavaScript “For …in” with Arrays
I looped over various arrays using for-in iteration, with varying results:
var my_array1 = {"foo":2, "bar":3};
var my_array2 = new Array(
'foo',
'bar'
);
var my_array3 = ["foo","bar"];
for (var key in my_array1){
alert(key); // outputs key
}
for (var key in my_array2){
alert(key); // outputs index integer not value
}
for (var key in my_array3){
alert(key); // outputs index integer not value
}
Is there a reason that the for-in iteration over non-associative arrays just gives the index and not the actual value like in python?
Is there an advantage to using for(var index in my_array) over using for(var index=0; index<my_array.length; index++), for non-associative arrays?
for..in iterates over properties, not values.
As described in the above link, a theoretical disadvantage of using it instead of a regular for with Arrays is that the iteration order of properties is not defined in the ECMAScript spec (see the text under this section), and is this implementation dependent.
Simply:
Your first array is not an array.
It's an object-literal.
Think of it as the instance of a class, where all properties and methods are public.
You could think of it as a singleton, if you really, really wanted, except without any of the global-scope issues that other languages create, trying to make singletons.
So in javascript for (key in obj) {} is meant to iterate through properties of a class-instance.
Use for (i = 0, length = x; i < length; i += 1) {} for iterating through arrays.
I'm guessing the reason basically boils down to being the way the whomever designed the Javascript 'in' operator. This behavior is similar to some other languages, in that in the case of the object/hash the keys are 'foo' and 'bar' while for an array the keys are the indexes. I wouldn't see a big difference between using a 'standard' for loop and a 'for in' loop for an array, although as a point of clarity I'd tend to used the standard notation unless I was using something like a .each() function which would take care of it for me.