I'm trying the following:
let foo = { a: 3, b: 4 };
let bar = { foo.a: 1, foo.b: 2 };
This doesn't work and to achieve this I'll have to do this:
let foo = { a: 3, b: 4 };
const c = foo.a;
const d = foo.b;
let bar = { c: 1, d: 2 };
Is there a way to do this using my first example?
Use computed property names:
let bar = { [foo.a]: 1, [foo.b]: 2 };
Example:
let foo = { a: 3, b: 4 };
let bar = { [foo.a]: 1, [foo.b]: 2 };
console.log(bar);
Related
What's wrong with this code? Why cant it sort the array according to the a key of the object?
It works when using dot notation in the condition but I want to use the second parameter in the condition instead of dot notation. Please help me getting the result.
This works:
if (objSort[i][`sortBy`] > objSort[j][`sortBy`]) {
[objSort[i], objSort[j]] = [objSort[j], objSort[i]]
}
This does not work:
function sortData(objSort, sortBy) {
for (let i = 0; i < objSort.length; i++) {
for (let j = i + 1; j < objSort.length; j++) {
if (objSort[i][`sortBy`] > objSort[j][`sortBy`]) {
[objSort[i], objSort[j]] = [objSort[j], objSort[i]]
}
}
}
console.log(data);
}
const data = [{ a: 4, b: 5 }, { a: 1, b: 10}, { a: 2, b: 5 }, { a: 14, b: 15 }, { a: 12, b: 3 }];
sortData(data,'a');
sortBy is your variable name, so remove it from the template literal:
if (objSort[i][sortBy] > objSort[j][sortBy]) {
That being said, your code is much more complex than it needs to be - there's no need for two loops and reorganising the array - just use sort():
const sortData = (objSort, sortBy) => objSort.sort((a, b) => a[sortBy] - b[sortBy]);
const data = [{ a: 4, b: 5 }, { a: 1, b: 10}, { a: 2, b: 5 }, { a: 14, b: 15 }, { a: 12, b: 3 }];
const result = sortData(data,'a');
console.log(result);
Example of what i'm trying to achieve
I want to make an object in react which will calculate one its key value from other keys using this function and the 'this' keyword so that I can use this function dynamically with many input fields object.
func = function (c) {
return this.a + this.b + c;
};
obj1 = {
a: 1,
b: 2,
value: func(5),
};
obj2 = [
{ a: 2, b: 3, value: func(6) },
{
a: 4,
b: 5,
value: func(7),
},
];
// expected result
console.log(obj1.value); // 8
console.log(obj2[0].value); // 16
I guess the simplest solution would to flip this around: Pass the object to the function, let it add the property and return the very same object:
const func = function (obj, c) {
obj.value = obj.a + obj.b + c;
return obj;
};
const obj1 = func({
a: 1,
b: 2,
}, 5);
const obj2 = [
func({ a: 2, b: 3 }, 6),
func({
a: 4,
b: 5,
}, 7),
];
// expected result
console.log(obj1.value); // 8
console.log(obj2[0].value); // 16
(no idea how the second example would result in 16 though)
At the moment func is called, this is set to window object, because the object you want to use it in, doesn't exist yet.
You can try returning a function from func
const func = function(c) {
return function() {
return this.a + this.b + c
}
}
const obj1 = {
a: 1,
b: 2,
value: func(5),
}
const obj2 = [{
a: 2,
b: 3,
value: func(6)
},
{
a: 4,
b: 5,
value: func(7)
}
]
// expected result
console.log(obj1.value()) // 8
console.log(obj2[0].value()) // 11
I have array of objects like this
const object1 = {
a: 'somestring',
b: 42,
c: false
};
const object2 = {
a: 'somestring2',
b: 42,
c: false
};
const object3 = {
a: 'somestring3',
b: 42,
c: false
};
const arr = [object1,object2,object3]
i want to get all the values of 'a' key.
so result be
['somestring','somestring2','somestring3']
I tried Object.values() but it gets me all values of all keys, which is not the desired output.
Just use map() function:
const arr = [object1,object2,object3].map(({a}) => (a))
An example:
const object1 = {
a: 'somestring',
b: 42,
c: false
};
const object2 = {
a: 'somestring2',
b: 42,
c: false
};
const object3 = {
a: 'somestring3',
b: 42,
c: false
};
const arr = [object1,object2,object3].map(({a}) => (a))
console.log(arr)
Have you tried const arr = [object1.a, object2.a, object3.a]? That might work
Is this piece of code:
const a = { aProp: 1 };
const c = {
b: { a }
};
the same as this piece of code:
const a = { aProp: 1 };
const c = {
b: a
};
?
I mean will c have exactly the same properties in both cases? And what technical differences are there in the code?
Thank you.
In a brief: no.
b: { a } is a shorthand for b: { a: a } so it will result in a nested property:
const c = {
b: { a: { aProp: 1 } },
};
In your second case:
b: a,
it's just a normal assignment, which will result in:
const c = {
b: { aProp: 1 },
};
Say I have an array of 3 objects like this:
[
{
a: 4,
b: 5,
c: 4
},
{
a: 3,
b: 5,
c: 6
},
{
a: 2,
b: 3,
c: 3
}
]
I would like to return an array of arrays containing the objects that share a common value for the property b. So the resulting array would contain only one array containing 2 objects like this:
[
[
{
a: 4,
b: 5,
c: 4
},
{
a: 3,
b: 5,
c: 6
}
]
]
How would I do this?
You could do this with map and filter
var data = [{"a":4,"b":5,"c":4},{"a":3,"b":5,"c":6},{"a":2,"b":3,"c":3}];
var check = data.map(e => {return e.b});
var result = [data.filter(e => { return check.indexOf(e.b) != check.lastIndexOf(e.b)})];
console.log(result)
To group multiple objects in separate arrays with same b values you can use map and forEach
var data = [{"a":4,"b":5,"c":4},{"a":3,"b":5,"c":6},{"a":2,"b":3,"c":3}, {"a":3,"b":7,"c":6},{"a":2,"b":7,"c":3}], result = [];
var check = data.map(e => {return e.b});
data.forEach(function(e) {
if(check.indexOf(e.b) != check.lastIndexOf(e.b) && !this[e.b]) {
this[e.b] = [];
result.push(this[e.b]);
}
(this[e.b] || []).push(e);
}, {});
console.log(result)
This proposal uses a single loop with Array#forEach but without Array#indexOf.
var array = [{ a: 4, b: 5, c: 4 }, { a: 3, b: 5, c: 6 }, { a: 2, b: 3, c: 3 }],
grouped = [];
array.forEach(function (a) {
this[a.b] = this[a.b] || [];
this[a.b].push(a);
this[a.b].length === 2 && grouped.push(this[a.b]);
}, Object.create(null));
console.log(grouped);
You can create a function that accepts fulfillment criteria and will return as many nested arrays as rules passed.
Let's say you have an array of objects, arr.
var arr = [{a: 1, b: 2}, {a: 3, b: 2}, {a: 3, b: 4}, {a: 1, b: 1}]
And you want to return an array with with nested arrays that fulfill a particular requirement, let's say you want objects with an a:1 and b:2.
You can create a function that loops through your rules and creates a nested array with the objects that fulfill each rule.
For example:
var arr = [{a: 1, b: 2}, {a: 3, b: 2}, {a: 3, b: 4}, {a: 1, b: 1}]
function makeNestedArrays() {
var rules = [].slice.call(arguments);
return rules.reduce(function(acc, fn) {
var nestedArr = [];
arr.forEach(function(obj) {
if (fn(obj)) {
nestedArr.push(obj);
}
});
// only push nested array
// if there are matches
if (nestedArr.length) {
acc.push(nestedArr);
}
return acc;
}, []);
}
var result = makeNestedArrays(
function(obj) { return obj.a === 1; },
function(obj) { return obj.b === 2; }
);
console.log(result);
This allows you to pass as many "rules" as you want, and will create a nested array for each rule so long as there is at least one match.
You could use a Map to group them, this should work with any kind of value (just be sure the equality rules check out):
var arr = [{
a: 4,
b: 5,
c: 4
}, {
a: 3,
b: 5,
c: 6
}, {
a: 2,
b: 3,
c: 3
}];
var result = arr.reduce(function(m, o){
var value = o.b;
if(m.has(value)){
m.get(value).push(o);
} else {
m.set(value, [o]);
}
return m;
}, new Map());
console.log(...(result.values()));
If you'd need to filter out the groups of 1:
var arr = [{
a: 4,
b: 5,
c: 4
}, {
a: 3,
b: 5,
c: 6
}, {
a: 2,
b: 3,
c: 3
}];
var result = arr.reduce(function(m, o){
var value = o.b;
if(m.has(value)){
m.get(value).push(o);
} else {
m.set(value, [o]);
}
return m;
}, new Map());
result = [...result.values()].filter(a => a.length > 1);
console.log(result);