What differences between these two ways of object declaration? - javascript

I was just wondering if there are any differences between these ways of JSON object declaration or they do the same thing? What is the standard (recommended) way to declare an object?
According to my test, they both give the same result.
let data1 = {
"record_1": [1,2,3],
"record_2": [4,5,6]
}
let data2 = {
record_1: [1,2,3],
record_2: [4,5,6]
}
console.log(data1);
console.log(data2);
console.log(data1.record_1);
console.log(data2.record_1);
console.log(data1.record_2);
console.log(data2.record_2);
console.log(JSON.stringify(data1));
console.log(JSON.stringify(data2));
Output:
{
record_1:(3) [...],
record_2:(3) [...]
}
{
record_1:(3) [...],
record_2:(3) [...]
}
(3) [
1,
2,
3
]
(3) [
1,
2,
3
]
(3) [
4,
5,
6
]
(3) [
4,
5,
6
]
{"record_1":[1,2,3],"record_2":[4,5,6]}
{"record_1":[1,2,3],"record_2":[4,5,6]}

Both of the declarations are valid in Javascript
let data1 = {
"record_1": [1,2,3],
"record_2": [4,5,6]
}
let data2 = {
record_1: [1,2,3],
record_2: [4,5,6]
}
but when it comes to JSON , data2 is invalid JSON syntax. You can verify at https://jsonlint.com/
One more diff is as below:
var obj = { "some key" : "Val" }; // Valid in JS
var obj = { some key : "Val" }; // invalid in JS
So for JS , both of these deceleration plays different role depending on the situation. Normally, data2 type declaration is widely used.

Object's property name are of type string, if you provide any other type then that is automatically converted to string.
var obj = {1: "one"}
var keyName = Object.keys(obj)[0];
console.log(`key Name ${keyName} and type is ${typeof keyName}`);
I will prefer the explicit way (using the quotes) of declaration as this will reduced the confusion (from the reader of the code).

They're essentially the same. One difference is that when you use quotes, you can use special characters as key.
// invalid
const noQuotes = {
key with spaces: 123
}
// valid
const withQuotes = {
"key with spaces": 123
}

Related

How can I filter an array containing varied object structures dynamically?

My usage will contain 6 different object types (some which contain double nested arrays), and any possibility of number of entries, on the condition that an given entry is unique.
These objects do not have a consistent unique identifier (a unique identifier is applied in backend on submission).
here is an example of what the array may look like (only 2 object types):
arr = [
{name:"aaa",time:15},
{name:"aaa",time:22},
{timeline: "250", chars[{a},{b},{c}]},
{timeline: "220", chars[{d},{e},{f}]},
]
obj = {name:"aaa",time:22}
My intention is to gain a true or false based on if obj is inside arr
I have tried methods:
I was suggested this method & it errors: #<Object> is not a function
console.log(arr.find(obj))
I also found this suggestion but it will always return false even with the element present
console.log(arr.includes(object))
I tried this method myself, though it will always fail.
console.log(arr.filter((element, index) => element === obj)
With attempt 4, If I was to compare name, this would be insufficient as unique time would be ignored missing valid entries.
If I was to pass every field, this would also not work as each object may or may not have the field and cause error.
Its not really possible to manually pre-filter filter into distinct categories, as every time a new type is added it will need manually adding to the filter.
If there is a library which could do this that you know of, please let me know as that would be perfect. Otherwise any other suggestions (excluding separating arrays) Would be greatly appreciated.
Use arr.some() to check if the required object is present in the array.
To compare the objects, a simpler way is to Stringify both the Objects and compare them.
const arr = [
{name:"aaa",time:15},
{name:"aaa",time:22},
{name: "aaa", chars: ["a", "b", "c"]},
{name: "bbb", chars: ["d", "e", "f"]},
]
const obj1 = {name:"aaa", time: 15}
const obj2 = {name:"aaa",chars: ["a", "b", "c"]}
console.log(arr.some((element) => JSON.stringify(element) === JSON.stringify(obj1))) // true
console.log(arr.some((element) => JSON.stringify(element) === JSON.stringify(obj2))) // true
Didn't give much thought on performance.
I didn't put much thought on performace here but this might help:
function checkObjectInArray(arr, obj) {
const res = arr.some((el) => deepEqual(el, obj));
console.log(res);
}
function deepEqual(obj1, obj2) {
if (Object.keys(obj1).length !== Object.keys(obj2).length) return false;
for (let prop in obj1) {
if (!obj2.hasOwnProperty(prop) || obj2[prop] !== obj1[prop]) {
return false;
}
}
return true;
}
in your case you can use it like:
arr = [
{ name: "aaa", time: 15 },
{ name: "aaa", time: 22 },
{ timeline: "250", data: ["2", "3", "4"] },
{ timeline: "251", data: ["2", "3", "4"] }, // what is chars[{d},{e},{f}] ?!
];
obj = { name: "aaa", time: 22 };
checkObjectInArray(arr, obj);
Observation : arr is not a valid array. Nested chars is not containing a valid value.
Solution : You can simply achieve the requirement by Just converting the JSON object into a JSON string and by comparing.
This solution works fine as you are just trying to find a single object in the passed arr.
Live Demo :
const arr = [
{name:"aaa",time:15},
{name:"aaa",time:22},
{timeline: "250", chars: [{a: 1},{b: 2},{c: 3}]},
{timeline: "220", chars: [{d: 4},{e: 5},{f: 6}]},
];
const obj = {name:"aaa",time:22};
const res = JSON.stringify(arr).indexOf(JSON.stringify(obj)) !== -1 ? true : false;
console.log(res);

Print objects and arrays in console log dynamically

I'm building a logger service. First argument is "msg" string and the second one in array of parameters (can be array or objects)
How can i iterate this parameters array and print in the console so the object/array can be seen\expand\collapse in the console?
For example if it's not dynamic i would do something like this:
console.log('str', obj1, obj2, obj3)
You mean something like this?
let arrayOfObjects = [
{ a: 1, b: 2 },
{ a: 3, b: 4, c: 5 }
];
let testMessage = "This is just a message";
console.log(testMessage, Object.values(arrayOfObjects));

javascript equivalent to [x for x in array]

Is there any operation in Javascript just like [x for x in array] in python?
For example, I'm using javascript to reading a json file where there're dozens of (key, value) pairs needed to be handled(or transformed into other format). And I thought working in this way is stupid:
let transformed = []
for (let key in json){
transformed = [ /* doing some transform*/ ]
}
Is there anything like:
let transformed = [
lambda function1(key), lambda function2(value) for key, value in json
]
Thanks in advance.
The rough equivalent of Python's list comprehension is Array.map:
const myArray = [1, 2, 3]
const transformed = myArray.map((item) => item + 1)
// [2, 3, 4]
But your example is not about an array, but about an Object with keys and values. In Python, this would be a dict, and you'd use a dict comprehension along the lines of {function1(key): function2(value) for key, value in my_dict.items()}.
In JavaScript, you can turn such an object into an array with Object.entries, then perform the map, and finally transform it back into an object using Object.fromEntries:
const myObject = { a: 1, b: 2 }
const transformed = Object.fromEntries(Object.entries(myObject)
.map(([key, value]) => [key + 'x', value + 1]))
// { ax: 2, bx: 3 }
Note that fromEntries is fairly new and you might need to add a polyfill for it.
You can use a code likes this. You must use a function that handle operation on current single item.
const words = ['hello', 'bird', 'table', 'football', 'pipe', 'code'];
const capWords = words.forEach(capitalize);
function capitalize(word, index, arr) {
arr[index] = word[0].toUpperCase() + word.substring(1);
}
console.log(words);
// Expected output:
// ["Hello", "Bird", "Table", "Football", "Pipe", "Code"]
First of all, javascript does NOT support Associative Arrays. If you are used to them in Python, PHP, and other languages you need to do a little workaround in JS to achieve the same functionality.
The most common way to simulate an associative array is using an object.
let testObject = {name: "Color", value: "Red"};
And then you push every object into an array so you end up with something like this:
let testArray = [{name: "Color", value: "Red"}, {name: "Color", value: "Blue"}];
Once you have this array consisting of objects, you can use map function to go through every object in the array and do whatever you want with it.
testArray.map((item, index) => {
console.log("The value of "+index+". item is: "item.value);
})
You can use Array.map() function. It work pretty like Array.forEach() function
const numbers = [1, 2, 3, 4, 5]
let newArray = numbers.map((element) => {
return element * 2
})
console.log(newArray) // excepted : [ 2, 4, 6, 8, 10 ]
It can be reduce using
const numbers = [1, 2, 3, 4, 5]
let newArray = numbers.map(element => element * 2)
console.log(newArray) // excepted : [ 2, 4, 6, 8, 10 ]
For more informations, you can this documentation https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Removing Duplicates in Arrays

I am trying to pass a function that removes duplicates from an array. It should handle strings, object, integers as well. In my code so far I am showing that it will handle strings but nothing else. How can Imake this function universalto handle numbers,handle arrays,handle objects, and mixed types?
let unique = (a) => a.filter((el, i ,self) => self.indexOf(el) ===i);
In this function I hav unique() filtering to make a new array which checks the element and index in the array to check if duplicate. Any help would be appreciated.
i think the first you should do is to sort the array ( input to the function ). Sorting it makes all the array element to be ordered properly. for example if you have in an array [ 1, 3, 4, 'a', 'c', 'a'], sorting this will result to [ 1 , 3 , 4, 'a', 'a' , 'c' ], the next thing is to filter the returned array.
const unique = a => {
if ( ! Array.isArray(a) )
throw new Error(`${a} is not an array`);
let val = a.sort().filter( (value, idx, array) =>
array[++idx] != value
)
return val;
}
let array = [ 1 , 5, 3, 2, "d", "q", "b" , "d" ];
unique(array); // [1, 2, 3, 5, "b", "d", "q"]
let obj = { foo: "bar" };
let arraySize = array.length;
array[arraySize] = obj;
array[arraySize++] = "foo";
array[arraySize++] = "baz";
array[arraySize++] = obj;
unique(array); // [1, 2, 3, 5, {…}, "b", "baz", "d", "foo", "hi", "q"]
it also works for all types, but if you pass in an array literal with arrays or objects as one of its element this code will fail
unique( [ "a", 1 , 3 , "a", 3 , 3, { foo: "baz" }, { foo: "baz" } ] ); // it will not remove the duplicate of { foo: "baz" } , because they both have a different memory address
and you should also note that this code does not return the array in the same order it was passed in , this is as a result of the sort array method
Try using sets without generics. You can write a function as
Set returnUnique(Object array[]) {
Set set=new HashSet();
for (Object obj:array) {
set.add(obj);
}
return set;
}

How do object references work internally in javascript

I am very new to javascript.
I have written the simple code:
var temp = {}
var arr = []
temp['a'] = ['a']
arr.push(temp)
console.log(arr);
As expected, it prints:
[ { a: [ 'a' ] } ]
But then, when I append the following line to the previous code:
temp['b'] = ['b']
arr.push(temp);
console.log(arr);
I would have expected it to print:
[ { a: [ 'a' ] }, { a: [ 'a' ], b: [ 'b' ] } ]
But it prints:
[ { a: [ 'a' ], b: [ 'b' ] }, { a: [ 'a' ], b: [ 'b' ] } ]
Entire code for unexpected result:
var temp = {}
var arr = []
temp['a'] = ['a']
arr.push(temp)
console.log(arr);
temp['b'] = ['b']
arr.push(temp);
console.log(arr);
Why did the first element of array got updated?
The following code gave me expected result:
var temp = {}
var arr = []
temp['a'] = ['a']
arr.push(temp)
console.log(arr);
temp = {};
temp['a'] = ['a']
temp['b'] = ['b']
arr.push(temp);
console.log(arr);
How does adding temp = {} helped here?
Objects in Javascript are passed by reference. That is, only one object is created and the symbol that represents that object can be used but it will refer to the same object always.
Lets take a deeper look:
If I'm understanding your example correct, this part
var temp = {}
var arr = []
temp['a'] = ['a']
arr.push(temp)
console.log(arr);
Creates a local variable temp to which you add ['a'] to. You then push that into arr.
So at this point, arr references the object temp and looks like this:
[ { a: [ 'a' ] } ]
When you do this:
temp['b'] = ['b']
arr.push(temp);
console.log(arr);
The temp symbol which points to the original object containing ['a'] is updated, and so the arr will also get updated, so arr contains this at that point:
[ { a: [ 'a' ], b: [ 'b' ] }, { a: [ 'a' ], b: [ 'b' ] } ]
Finally,
You then do this instead:
temp = {};
temp['a'] = ['a']
temp['b'] = ['b']
arr.push(temp);
console.log(arr);
This creates a separate global variable temp, onto which you add both
['a'] and ['b']. This is global because it does not have the var keyword in the declaration/initialization. This then gets pushed into the arr. However, since it's a global variable and not the original local variable, you see this instead:
[ { a: [ 'a' ] }, { a: [ 'a' ], b: [ 'b' ] } ]
In first case, arr[0] has temp's reference, arr[1] also has temp's reference. So, arr[0] and arr[1] have the same reference.
Hence updating the reference will update it everywhere where the reference is
being referred.
In second case however, when you do temp = {} you're just reassigning temp to a new reference, before pushing it. So, there's no relationship between the arr[0]'s reference, and hence updating temp now, only affects it.
The examples are not the same, it doesn't have to do with temp = {}.
In the first example you push temp twice, meaning arr has to references 2 temp.
After the first push you add another item to temp so within arr, if you had print it, you would have seen:
[ { a: [ 'a' ], b: [ 'b' ] } ]
So try this out on the console:
var temp = {}
var arr = []
temp['a'] = ['a']
arr.push(temp)
temp['b'] = ['b']
console.log(arr);
You'll see the result:
[ { a: [ 'a' ], b: [ 'b' ] } ]
Pushing another temp into arr is just going to result into two references into temp.
There are two data types in JavaScript - value types and reference types.
Value types are actually copied as they are sent between objects. This is because this is what you would expect for certain things like numbers and booleans.
Say I pass the number 1 to a function that stores it in an object A.
It would be surprising if I could then subsequently modify the value contained in A simply by modifying the value of the original number. Hence, pass by value. There are also optimizations that can be performed for value types.
Objects (i.e. everything other than number literals, boolean literals, null, undefined, and string literals*) are reference types in JavaScript and only their reference is passed around. This is largely for efficiency reasons. In your example, temp is an object. It is therefore passed by reference.
And so
temp['b'] = ['b']
Modifies the single existing instance of temp, thereby modifying the contents of arr, before you then also push temp into arr for a second time.
So you end up with an array containing two references to a single object temp, giving you the observed result.
* There is some complexity surrounding the string implementation that I am purposefully ignoring here.

Categories