Write a function that accepts any number of objects, and returns a single object that contains all the fields of the original objects.
If the same key is found in several objects, you should leave the meaning that was first met. My solution does not give the correct result.
function zip() {
const appliedValues = Object.assign({}, ...objects);
return appliedValues;
}
const objects = [
{ foo: 5, bar: 6 },
{ foo: 13, baz: -1 } // foo - repeating key
];
zip(...objects); // I expect { foo: 5, bar: 6, baz: -1 }
Make the record look like this: { foo: 5, bar: 6, baz: -1 }
enter image description here
One very quick change that would achieve this is to simply reverse the passed in array, which will result in the earlier items being used where possible.
To avoid mutating the original array, we can create a copy with [...objects] and then use .reverse() (documentation)
function zip() {
const appliedValues = Object.assign({}, ...[...objects].reverse());
return appliedValues;
}
const objects = [
{ foo: 5, bar: 6 },
{ foo: 13, baz: -1 }
];
console.log(zip(...objects));
I'm currently transitioning from VueJS to AlpineJS and trying to update specific JSON arrays but it doesn't seem to be updating.
An example:
Any tips or reasonings why this is not working?
var foo = [
{ id: 0, title: 'test', text: c( this ) },
{ id: 1, title: 'test', text: 'text' },
{ id: 2, title: 'test', text: 'text' },
]
function c( idk ) {
console.log( idk.title )
}
console.log(foo)
var foo = (() => {
// Paste in your original object
const foo = [ {
a: 5,
b: 6,
}
];
// Use their properties
foo.c = foo.a + foo.b;
// Do whatever else you want
// Finally, return object
return foo;
})();
console.log( foo )
These examples were from Self-references in object literals / initializers but has been modified to use an Array of JSON
The first example doesn't work for exactly the same reason as the question you referenced.
The second example doesn't work because foo is the array and not the object inside the array.
foo.a + foo.b is going to be undefined + undefined which you then assign to foo.c making foo.c Not A Number.
You then console.log the array and it doesn't show the c property because it is an array and not designed to have named properties added to it.
var foo = (() => {
const foo = [{
a: 5,
b: 6,
}];
console.log(foo.a, foo.b);
foo.c = foo.a + foo.b;
console.log(foo.c);
return foo;
})();
console.log(foo.c)
I have an array of objects I want to destructure, retrieving both the first object and a value within it:
const [{ a }] = ([firstObjectInArray] = [
{
a: 1,
},
{
b: 2,
},
]);
console.log(a); // 1
console.log(firstObjectInArray); // { a: 1 }
In Javascript this works; but in TypeScript this returns
Cannot find name 'firstObjectInArray'.ts(2304)
I'm trying to figure out how to type that in order to avoid the error.
As firstObjectInArray isn't part of your declaration (it's just an expression), it's an assignment to an undeclared variable.
To solve the issue, you have two ways:
Do it in two steps:
const [firstObjectInArray] = [
{
a: 1,
},
{
b: 2,
},
];
const {a} = firstObjectInArray
console.log(a); // 1
console.log(firstObjectInArray); // { a: 1 }
Declare the firstObjectInArray earlier:
let firstObjectInArray; //<-- This can't be made `const`, as it has no initializer
const [{ a }] = ([firstObjectInArray] = [
{
a: 1,
},
{
b: 2,
},
]);
console.log(a); // 1
console.log(firstObjectInArray); // { a: 1 }
This question already has answers here:
Clean way to keep original variable and destructure at the same time
(5 answers)
Closed 2 years ago.
I have an object. I know I can destructure to retrieve the value of any entry, and use spread operator to retrieve the rest of them
const [a, ...rest] = [1, 2, 3];
console.log(a); // 1
console.log(rest); // [ 2, 3 ]
I would like to know if there is any sintaxis to retrieve both a value of any entry, and the object itself redeclared to a new var, something like the following —although I know is wrong—:
const [a], myArrayInANewVar = [1, 2, 3];
console.log(a); // 1
console.log(myArrayInANewVar); // [ 1, 2, 3 ]
Thanks in advance!
Why not take two assignments?
const myObject = {
a: 1,
b: 2,
};
const
{ a } = myObject,
{ ...copy } = myObject;
console.log(a);
console.log(copy);
A chained assignemnt does not work because the nested variables are created outside of the actual scope.
function ownScope() {
const
myObject = { a: 1, b: 2, },
{ a } = { ...copy } = myObject;
console.log(a);
console.log(copy);
}
ownScope();
console.log(copy); // global
const [a] = (myArrayInANewVar = [1, 2, 3]);
console.log(a); // 1
console.log(myArrayInANewVar); // [ 1, 2, 3 ]
I have class that has a private array and a getter that returns a filtered version of said array. I would like to be able to simply call a push onto the filtered array which would update the underlying array without having to directly call the underlying array. I've tried accessing the array prototype but couldn't quite figure out how to do so.
Here's a code snippet to emulate what I'm trying to do:
class Test {
_foo: number[];
constructor() {
this._foo = [1,2,3,4,5];
}
get foo(): number[] {
return this._foo.filter(x => {
return x > 2;
});
}
}
let obj = new Test();
obj.foo.push(6);
console.log(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
Any advice is appreciated.
alternative via override:
const {create} = Object;
class Test {
_foo: number[];
_push: Object;
constructor() {
this._foo = [1,2,3,4,5];
this._push = {push: {value: this._foo.push.bind(this._foo)}};
}
get foo(): number[] {
return create(this._foo.filter(x => x > 2), this._push);
}
}
let obj = new Test();
obj.foo.push(6);
console.log(obj.foo.slice()); // 3,4,5,6
You could also use directly:
get foo(): number[] {
const filtered = this._foo.filter(x => x > 2);
filtered.push = this._foo.push.bind(this._foo);
return filtered;
}
or assign this._push once in the constructor as function and do the same, however this might de-optimize in some JS engine (i.e. v8)
You could just have a public method, to do that?
class Test {
_foo: number[];
constructor() {
this._foo = [1,2,3,4,5];
}
get foo(): number[] {
return this._foo.filter(x => {
return x > 2;
});
}
push(x: number) {
this._foo.push(x);
}
}
let obj = new Test();
obj.push(6);
console.log(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
I wouldn't recommend doing this, but if you just need to support push() in a way that updates the backing array (as well as the, uh, "fronting" array), and you don't need to modify things with any other method (such as indexed access), you can do something like this:
class Test {
_foo: number[];
constructor() {
this._foo = [1, 2, 3, 4, 5];
}
get foo(): number[] {
const _foo = this._foo;
const filt: number[] = [];
filt.push = (...args: number[]) => {
_foo.push(...args); // push onto original array
filt.splice(0, filt.length, ..._foo.filter(x => x > 2)); // re-filter
return filt.length;
};
filt.push(); // initialize
return filt;
}
}
Here we are returning a filtered array with a custom push() method that updates itself and the backing array. Here's how it acts:
let obj = new Test();
console.log(obj.foo); // [3, 4, 5]
console.log(obj._foo); // [1, 2, 3, 4, 5]
obj.foo.push(6);
console.log(obj.foo); // [3, 4, 5, 6]
console.log(obj._foo); // [1, 2, 3, 4, 5, 6]
obj.foo.push(9, 10, 11);
console.log(obj.foo); // [3, 4, 5, 6, 9, 10, 11]
console.log(obj._foo); // [1, 2, 3, 4, 5, 6, 9, 10, 11]
obj.foo.push(1, 1000, 0, 2000);
console.log(obj.foo); // [3, 4, 5, 6, 9, 10, 11, 1000, 2000]
console.log(obj._foo); // [1, 2, 3, 4, 5, 6, 9, 10, 11, 1000, 0, 2000]
I... think that's what you want? But really I'd recommend against things with unusual side effects like this. Giving Test a public pushFoo() method seems to be the most conventional approach.
Good luck!
Link to code
You can use a Setter to push into foo
set foo(x) {
this._foo.push(x);
}
class Test {
constructor() {
this._foo = [1, 2, 3, 4, 5];
}
set foo(x) {
this._foo.push(x);
}
get foo() {
return this._foo.filter(x => {
return x > 2;
});
}
}
let obj = new Test();
obj.foo = 6;
console.log(obj.foo);