I have an object which could include a mix of properties e.g.
{a: 1}, {b: 4}, {c: 2}, {a: 3, b: 1}
it will be a key with a count value next to it.
I'd like to set a bunch of variables depending on which key names are in the object, for instance:
aOnly = {a: 1}, mixOfAB = {a: 3, b: 1}
I'm using this logic in a function which will eventually return a string value. What's the best way to operate on this object, I tried using a switch but it didn't work so well. I could use a large number of if/else statements but is there something more neater?
You could do something like this:
vars = {}
function setVariable(obj) {
keys = Object.keys(obj)
name = keys.length == 1 ? keys[0] + 'Only' : 'mixOf' + keys.join('').toUpperCase()
vars[name] = obj
}
setVariable({a: 1})
console.log(vars)
setVariable({b: 4})
console.log(vars)
setVariable({c: 2})
console.log(vars)
setVariable({a: 3, b: 1})
console.log(vars)
Related
I would like to compare the performances of comparing two objects in JavaScript having a unique id 'key' using their key or equality sign i.e: object1 === object2 or object1.key === object2.key.
While both are working I am wondering is it better to compare directly the keys as it will have only two values to compare or is Javascipt comparing each key / value in each value and then the complexity would be O(n) (n being the muber of keys of an object)
Is it comparing addresses or something to make it efficient?
Case 1. comparing distinct objects:
While both are working
Well they don't :
{a: 1} == {a: 1} // false
you can't compare two distinct objects by two (or three) equal sign. you have two way:
JSON.stringify({a: 1}) === JSON.stringify({a: 1})
Or:
{key: 1, a: 1}.key === {key: 1, a: 1}.key
Which obviously the second one is more efficient.
Case 2. Comparing non-distinct objects like:
var obj1 = {key: 1, a: 1, b: 2}
var obj2 = {key: 2, a: 1, b: 2}
var obj3 = obj1
obj3 === obj1 // true
There is no difference between comparing them directly or comparing them by your keys, both are O(1) since js will compare them by refrence, not by comparing their key-values.
Is there a way using lodash or another library to join an array of objects?
I'm looking for a readymade function not a for loop.
For example:
[{a: 1}, {a:3}, {a: 4}]
//Run a function by specifing the property a and setting "," as the delimeter
Get 1,3,4
Here is your lodash answer
var arr = [{a: 1}, {a:3}, {a: 4}];
var s = _.map(arr, 'a').join(',');
//s == '1,2,3,4'
You don't need lodash for this, you can just use map and join:
let collection = [{a: 1}, {a:3}, {a: 4}];
alert(collection.map(item => item.a).join(','));
I was trying to change the structure of a Javascript object and I don't understand the results I am receiving from the logs.
I have the following object: a = {e: 1, f: 2}
And I want to move it to a.b
If I do a.b = a then I receive these results:
console.log(a) // {e: 1, f: 2}
console.log(a.b) // {e: 1, f: 2}
While I am expecting something like this:
console.log(a) // {b: {e: 1, f: 2}}
console.log(a.b) // {e: 1, f: 2}
Can someone explain me why this is happening?
Assigning a value in JS doesn't move it, it copies it.
You are adding a b property to the existing object.
It isn't shown in the log because console.log protects itself against infinite recursion by not displaying the property.
a.b = a simply assigns a.b as a reference to a, which causes a to become a recursive object:
var a = {e: 1, f: 2};
a.b = a;
console.log(a.e, a.f); //1 2
console.log(a.b.e, a.b.f); //1 2
console.log(a.b.b.e, a.b.b.f); //1 2
console.log(a.b.b.b.e, a.b.b.b.f); //1 2
To actually move a's properties into a.b, you'll need to overwrite the existing object, assigning a new property b to its existing value:
var a = {e: 1, f: 2};
a = {b: a};
console.log(a); //{b: {e: 1, f: 2}}
sry if this question is still there but i searched for it and i didn´t find a solution. Also i couldn´t get any hint out of the Developer.Mozilla website where Objects.assign etc. is described well.
The question:
How can i change the children of an object? With exactly the output i described in the following.
Sample-Code
var obj= {test: [{a: 2}, {b: 3}]};
var newChildren = [{a: 3}, {b: 5}, {c: 1}];
//I read the obj key value by the following:
var objKey = Object.entries(obj)[0][0]
//Here i want to have some code to get the following result
//My momentary regarding to #webdeb
var output = Object.assign({}, {objKey: newChildren})
actual output: // {objKey: [{a: 3}, {b: 5}, {c: 1}]}
wanted output: // {test: [{a: 3}, {b: 5}, {c: 1}]}
I have no other option to get the code in some other format so the "input" is needed in the way i described. And i need to set the objKey as a variable, because i have multiple keys in my code wich i have to set for multiple children. (Doing some filter stuff)
Thanks for your help
BR
Jonathan
First of all, don't use Object as variable Name..
Ok, lets say the Object is now obj
Without modification of the obj
var newObj = Object.assign({}, obj, {test: newChildren})
Or just, (modifies the obj)
obj.test = newChildren
Is it what you are looking for?
Following solution gave me the exact result i wanted:
obj[objKey] = newChildren;
console.log(obj) // {test: [{a: 3}, {b: 5}, {c: 1}]}
I took this solution regarding to the question:
How can I add a key/value pair to a JavaScript object?
The importance for me was to have the object-key as a variable. The described solution gives me the option to add a value tomore than just one static key.
Given the following:
var xs = [{a: 1}, {a: 2}, {a: 3}];
R.findIndex(R.propEq('a', 2))(xs); //=> 1
R.findIndex(R.propEq('a', 4))(xs); //=> -1
How do I create a new function that does not bind propEq immediately.
I thought curry might do it.
var myfn = R.findIndex(R.propEq);
myfn('a', '2')(xs); // => 1
I tried curry, but I don't have it quite correct.
var myfn = R.findIndex(R.curry(R.propEq)); // functional programming is rusty - this is not currect
Well, my first thought is that simply being explicit would be best here:
const findByProp = curry((key, val, xs) => findIndex(propEq(key, val), xs));
const xs = [{a: 1, b: 10}, {a: 2, b: 20}, {a: 3, b: 30}];
findByProp('a', 1, xs); //=> 0
findByProp('a', 2)(xs); //=> 1
findByProp('b')(30)(xs); //=> 2
There might be some way to make this points-free using useWith or converge or Sanctuary's S combinator, but they would probably in the end not be as readable as this.
You can see this in action on the Ramda REPL.