JavaScript arr.every() method? - javascript

I was looking into Javascript .every documentation and it have a second parameter which is passed the description says
Optional. Value to use as this when executing the callback. If a thisArg parameter is provided to every, it will be used as callback's this value. Otherwise, the value undefined will be used as its this value. The this value ultimately observable by the callback is determined according to the usual rules for determining the this seen by a function.
which means that I can access that values as this in the callback function, what is a practical example of this?

As per MDN,
Optional. Value to use as this when executing callback. [Ref]
It means, you can use provided value as this in callback function to test the value.
const data = [0, 1, 2, 3];
const doesPass = data.every(function(el) {
return el < this.toTest;
}, {
toTest: 4
});
console.log(doesPass);

Every iteration method of Array contains thisArg as second parameter. This is an example for filtering object keys with another object by using a prototype, which usually requires an object, which is handed over as argument, or in the second a bound to the method.
var firstObject = { x: 0, y: 1, z: 2, a: 10, b: 20, e: 30 },
secondObject = { x: 0, y: 1, z: 2, a: 10, c: 20, d: 30 };
function intersection(o1, o2) {
return Object.keys(o1).filter(Object.prototype.hasOwnProperty, o2);
}
console.log(intersection(firstObject, secondObject));
The same with previously bound o2.
var firstObject = { x: 0, y: 1, z: 2, a: 10, b: 20, e: 30 },
secondObject = { x: 0, y: 1, z: 2, a: 10, c: 20, d: 30 };
function intersection(o1, o2) {
return Object.keys(o1).filter(Object.prototype.hasOwnProperty.bind(o2));
}
console.log(intersection(firstObject, secondObject));

Related

what's the best way to convert an array to an object with some special keys like x & y with typescript?

I just want to write a simple function which converts an array with 2 values [7, 9] to an object with x & y keys like : { x: 7, y: 9 }
interface coordinates {
x: number;
y: number;
}
function getAnObjectOfnum(arr: number[]): coordinates;
function getAnObjectOfnum(arg1: unknown, arg2?: unknown): coordinates {
let coord: coordinates = {
x: 0,
y: 0,
};
if (Array.isArray(arg1)) {
const converted = arg1.reduce((a, v, i) => ({ ...a, [i]: v }), {});
}
return coord;
}
console.log(getAnObjectOfnum([7, 9]));
That's my effort to find the solution.
I just want to write a simple function which converts an array with 2 values [7, 9] to an object with x & y keys like : { x: 7, y: 9 }
Unless there are requirements you're not describing in the question, it can be much simpler than that:
function getAnObjectOfnum(arr: [number, number]): coordinates {
return {x: arr[0], y: arr[1]};
}
Playground link
Note that I've used [number, number] rather than number[], since we need exactly two values. This is a tuple type.
That can be made more concise using parameter destructuring, but possibly at the expense of clarity (or possibly not; if you're familiar with destructuring, it's clearer than I would have thought):
function getAnObjectOfnum([x, y]: [number, number]): coordinates {
return {x, y};
}
Playground link

Object.assign(...as) changes input parameter

Object.assign(...as) appears to change the input parameter. Example:
const as = [{a:1}, {b:2}, {c:3}];
const aObj = Object.assign(...as);
I deconstruct an array of object literals as parameter of the assign function.
I omitted console.log statements. Here's the stdout from node 13.7:
as before assign: [ { a: 1 }, { b: 2 }, { c: 3 } ]
aObj: { a: 1, b: 2, c: 3 }
as after assign: [ { a: 1, b: 2, c: 3 }, { b: 2 }, { c: 3 } ]
The reader may notice that as first element has been changed in an entire.
Changing a new array bs elements to an immutable object (using freeze)
const bs = [{a:1}, {b:2}, {c:3}];
[0, 1, 2].map(k => Object.freeze(bs[k]));
const bObj = Object.assign(...bs);
leads to an error:
TypeError: Cannot add property b, object is not extensible
at Function.assign (<anonymous>)
Which indicates the argument is indeed being changed.
What really confounds me is that even binding my array, cs, by currying it to a function (I think you call this a closure in JS)
const cs = [{a:1}, {b:2}, {c:3}];
const f = (xs) => Object.assign(...xs);
const g = () => f(cs);
const cObj = g();
returns:
cs before assign: [ { a: 1 }, { b: 2 }, { c: 3 } ]
cObj: { a: 1, b: 2, c: 3 }
cs after assign: [ { a: 1, b: 2, c: 3 }, { b: 2 }, { c: 3 } ]
What went wrong here? And how may one safely use Object.assign without wrecking its first argument?
Object.assign is not a pure function, it writes over its first argument target.
Here is its entry on MDN:
Object.assign(target, ...sources)
Parameters
target
The target object — what to apply the sources’ properties to, which is returned after it is modified.
sources
The source object(s) — objects containing the properties you want to apply.
Return value
The target object.
The key phrase is "[the target] is returned after it is modified". To avoid this, pass an empty object literal {} as first argument:
const aObj = Object.assign({}, ...as);

Is there a way to ensure javascript object properties are ordered in a specific way?

I have a JavaScript object that looks like this:
Const data = {
x: 1,
y: 2,
z: 3
a: 4,
b: 5,
c: 6
};
We have a signing service in our Angular 6 application which stringifies this object, hashes the string, then attached a signature to it. Then it saves it to a firestore database. The database likes to order the properties alphabetically so it ends up looking like this:
{
a: 4,
b: 5,
c: 6,
x: 1,
y: 2,
z: 3
}
When we retrieve this object from the database and try to validate the signature, it fails. It fails because when you stringify this object, the alphabetical order of the properties results in a different string compared to when we signed it. This results in a different hash which doesn’t match with the original signature.
Our current solution to this problem is that we write out the order of the properties alphabetically in the code, but we’d like to make this fool proof (ex. If another developer comes along and adds a property to the bottom, say d, not realizing it’s supposed to be alphabetical). I’m told by a colleague that there is some way of telling Javascript to order the properties according to its own algorithm. If we could do that, then we’d order the properties according to that algorithm before stringifying, hashing, and signing, and then when we retrieve the object from the database, do the same thing: order the properties according to Javascript’s algorithm, stringify, hash, and validate.
Does anyone know what this Javascript ordering is and how to do it?
There isn't a way for JS to naturally order an object, you're going to have to tinker with it yourself.
The easiest way that I can think of to do this would be to use an array and sort from there.
This will return you the following array...
Object.entries(test).sort((a, b) => a[1] - b[1])
returns
[ [ 'x', 1 ],
[ 'y', 2 ],
[ 'z', 3 ],
[ 'a', 4 ],
[ 'b', 5 ],
[ 'c', 6 ] ]
If you want it back in an object,
Object.assign({}, ...Object.entries(test).sort((a, b) => a[1] - b[1]).map(([key, value]) => ({[key]: value})) )
returns
{ x: 1, y: 2, z: 3, a: 4, b: 5, c: 6 }
Create a custom stringify function that handles putting the object in the correct order.
const data = {
a: 4,
b: 5,
c: 6,
x: 1,
y: 2,
z: 3
}
function customStringify(d){
return '{'+Object
.entries(d)
.sort(([,v1],[,v2])=>v1-v2)
.map(([k,v])=>`${k}:${v}`)
.join(",")+'}';
}
const res = customStringify(data);
console.log(res);

Merging or appending array of objects in different object

I am using angularjs where I have a $scope.var1 ={a:10, b:20, c:30}; in which I want to append another value(s) which is infact an array of objects i.e. $scope.myobjects=[{m:10, n:30}, {x:6, y:8}, ....]; after appending this value my $scope.var1 should look like, $scope.var1={a:10, b:20, c:30, m:10, n:30, x:6, y:8};
any idea please.
Thanks
obj ={a:10, b:20, c:30};
arr=[{m:10, n:30}, {x:6, y:8}];
arr.forEach(function(a){
Object.keys(a).forEach(function(key){
obj[key]=a[key];
})
})
console.log(obj);
You could iterate the array and use Object.assign.
The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.
If not on the user agent available, like on IE, you could use a polyfill.
var target = { a: 10, b: 20, c: 30 };
objects = [{ m: 10, n: 30 }, { x: 6, y: 8 }];
objects.forEach(function (o) {
Object.assign(target, o);
});
console.log(target);
Object.assign.apply(null, [$scope.var1].concat($scope.myobjects))
Please try this one:
var var1 = { a: 10, b: 20, c: 30 };
myobjects = [{ m: 10, n: 30 }, { x: 6, y: 8 }];
myobjects.forEach(function (o) {
for (var p in o) {var1[p] = o[p]};
});
console.log(var1);
Note that this code simply add/update properties based on source object

Parse.com retrieving value of nested object

Lets say i have object like this:
var a = {
b: {
c: 1,
d: 2
}
}
And i have saved this object in Parse backend. There are 100 objects, but with different c and d values. Can i do search searching only objects which contains d:2. Or the only way is to query all objects and then use for loop which will search for d:2?
Dont read this!
Writting this line just to get posted, because system does not allow to post me question, dont know why
Thank you
Update
Maybe i am not clear enough, I am using parse.com you can retrieve objects by using this line:
var GameScore = Parse.Object.extend("GameScore");
var query = new Parse.Query(GameScore);
query.equalTo("playerName", "Dan Stemkoski");
query.find();
If anybody knows if you can retrieve objects with specific values in nested objects, that would be great.
You can do something like this
var a = {
b0: {
c: 1,
d: 2
},
b1: {
c: 5,
d: 3
},
b2: {
c: 1,
d: 4
},
b3: {
c: 2,
d: 2
},
b4: {
c: 1,
d: 4
},
b5: {
c: 7,
d: 2
},
},
d2s = Object.keys(a).filter(e => a[e].d == 2).map(e => a[e]);
document.write("<pre>" + JSON.stringify(d2s,null,2) + "</pre>");

Categories