i want to know if i can set the same value for multiple keys in the following:
React functional component state:
const [state, setState] = useState(
key1: 'same-value',
key2: 'same-value',
key3: 'same-value'
);
React class component state:
state = {
key1: 'same-value',
key2: 'same-value',
key3: 'same-value'
};
Javascript object:
const state = {
key1: 'same-value',
key2: 'same-value',
key3: 'same-value'
};
I want to know if something like this is possible:
const state = {
state1, state2, state3: 'same-value';
};
I want to know if something like this is possible
Not in an object literal, no. You can do it after creating the object:
const state = {};
state.key1 = state.key2 = state.key3 = 'same-value';
Or you could make key2 and key3 accessor properties for key1, meaning they'd track its value (change key1, and you see the change in key2 and key3), because although using them looks like a simple property access, in fact it's a function call.
const state = {
key1: 'some-value',
get key2() { return this.key1; },
get key3() { return this.key1; }
};
console.log(state.key1); // 'some-value'
console.log(state.key2); // 'some-value'
console.log(state.key3); // 'some-value'
I'm not suggesting that, just noting it's possible.
Related
I'm not totally sure if I'm using the correct terminology or not, I'm relatively new to node.
I have two JSON objects
const objA = {
key1: value1
...
}
const objB = {
key2: value2
...
}
that I want to combine into one while keeping the two object names, so it would look a bit like:
const newObj = {objA: { key1: value1,...}, objB: { key2: value2,...}}
So far in my research I've found Object.assign(objA,objB) which just combines them as newObj = {key1: value1, key2: value2, ...}
Is there a way to do what I want?
const newObj = {objA, objB};
You can assign them into new object like above.
Just putting it out there as a reference if you wanted to combine the key and values from both objects into one you could always use spread syntax if you decide to not go with a multi-level object:
const objA = {
key1: "value1"
}
const objB = {
key2: "value2"
}
const objCombined = {...objA, ...objB }
console.log(objCombined)
I have a key value pair:
`{good: 'value1', key2: 'value2': key3: 'value3'}
I want to convert it as the following:
[{key: 'good', value:'value1'}, {key: 'key2', value: 'value2'}, {key: 'key3', value: 'value3']
So far, I am able to convert them into an array with Object.entries, but I am unable to get my desired result.
There exists a method Object.entries that turns object into list of keys and values already, mapping it to match your required format should not be difficult.
const data = {good: 'value1', key2: 'value2', key3: 'value3'};
const result = Object.entries(data).map(([key, value]) => ({key, value}))
console.log(result)
You can do it like this:
const data = {good: 'value1', key2: 'value2', key3: 'value3'};
const result = [];
Object.keys(data).forEach(key => {
result.push({key, value: data[key]})
})
console.log(result)
To transform arrays, javascript provides a variety of array methods. map, foreach, reduce. etc. (Read more)
Object.entries( data ) converts your object into an array of arrays where each inner array is a key-value pair like this
[ [key1, value1], [key2, value2] ....]. (Read More)
Your usecase:
const data = { good: 'value1', key2: 'value2', key3: 'value3' };
const entries = Object.entries(data);
// [ ["good","value1"], ["key2","value2"],["key3","value3"] ]
// Map those entries to your desired form.
const results = entries.map( entry => ({ key: entry[0], value: entry[1] }) ) ;
// Or leverage the destructuring fetaure
// const results = entries.map( ([key, value]) => ({ key, value }) ) ;
console.log(results)
In case if you are interested in fast solution:
type Values<T> = T[keyof T]
type Mapper<T> = {
[Prop in keyof T]: { key: Prop, value: T[Prop] }
}
type Convert<T> = Array<Values<Mapper<T>>>
function convert<
Prop extends string,
Value extends string,
Obj extends Record<Prop, Value>
>(obj: Obj): Convert<Obj>
function convert<
Prop extends string,
Value extends string,
Obj extends Record<Prop, Value>
>(obj: Obj) {
const result: {
key: Extract<keyof Obj, string>;
value: Obj[Extract<keyof Obj, string>];
}[] = []
for (let prop in obj) {
result.push({
key: prop,
value: obj[prop]
})
}
return result
}
const result = convert({ good: 'value1', key2: 'value2', key3: 'value3' })
const first = result[0]
if (first.key === 'good') {
// {
// key: "good";
// value: "value1";
// }
first
}
Cons:
convert function creates internal result variable and mutates it. It is possible to use recursion instead of mutation result but I'm not sure this trade of worth it.
Pros
Faster than entries & map
Convert types maps type of argument to the type you want to achieve but only in type scope, whereas function maps argument in runtime scope.
If performance is not critical, you probably should stick with other solution where Object.entries is used
I would like to add or delete object to another object through react state. How can I achieve this?
code is like this:
const [ stateObj, setStateObj ] = usetState({
obj1: {},
obj2: {},
obj3: {}
})
I want to add some objects temp1,temp2,temp3,... inside obj1, such as:
setState({ ...stateObj, obj1: {...obj1,temp1} })
setState({ ...stateObj, obj1: {...obj1,temp2} })
...
but this seems not correct, this keeps obj1 one item only
how can I add temp1,temp2,... into obj1 by state?
and also the method for delete temp1, temp2,...?
be careful we should copy the state first:
Never mutate state directly, as calling setState() afterwards may replace the mutation you made. Treat state as if it were immutable.
const temp1 = { a: 1 };
const temp2 = { b: 2, c: 3 };
const prevState={...stateObj};
const newObj1 = { ...prevState.obj1, ...temp1, ...temp2 };
setStateObj({ ...prevState, obj1: newObj1 });
console.log(stateObj);
here is an example just with javascript
const stateObj = {
obj1: {},
obj2: {},
obj3: {}
};
const temp1={a:1};
const temp2={b:2,c:3};
const newObj1={...stateObj.obj1,...temp1,...temp2};
const updatedState={...stateObj,obj1:newObj1}
console.log(updatedState)
You're calling setState simultaneously, so the state is updated only once with the last value. setState is batched together as it is not synchronous. You have to update the state with the previous state
You could try this code:
setStateObj(prevState = > {
return {
...prevState,
obj1: {
...obj1,
temp1
}
}
})
I am trying to convert all elements of a given key in a list of objects. The specific change is to convert an generic object to a Long object with the same values.
Input:
[obj1, obj2, obj3, ...]
Where each object looks like:
{
key1: value1, // value1 is an object
key2: value2
}
So the goal here is to get a very similar array, but where key1 is transformed from just object to a long object, in my example incremented by one.
Output:
[obj1, obj2, obj3]
Where each object is:
{
key1: value1, // value1 is now a Long object
key2: value2
}
I tried with mapping over the array and then spreading over the objects entries, but did not succeed.
Any help would be highly appreciated.
You don't really need to map here, unless you want to create one more new array. Simple loop would be enough, just update key1 or each object:
[obj1, obj2, obj3].forEach(obj => {
obj.key1 = obj.key1 + 1
})
Since the array holds object - any modification to object reflect the actual input being passed. You need to make a copy of your object and perform the logic.
Your logic,
var input = [obj1, obj2, obj3];
var output = input.map(function(obj){
obj.key1 = obj.key1 + 1;
return obj;
});
console.log(input[0]===output[0]); //true
Solution:
var output = input.map(function(obj){
var _objCopy = Object.assign({}, obj);
_objCopy.key1 = _objCopy.key1 + 1;
return _objCopy;
});
console.log(input[0]===output[0]); //false
how about dynamically first key of any object es6 way
const myObject0 = {
'foo1': { name: 'myNam1' },
'foo2': { name: 'myNam2' }
};
const myObject1 = {
'yo': { name: 'myNam1' },
'boh': { name: 'myNam2' }
};
[myObject0, myObject1].forEach(obj => {
let getFirstKey = Object.keys(obj)[0];
getFirstKey = getFirstKey + 1;
console.log(getFirstKey);
});
Thanks for all the answers guys.
I ended up with the following:
Given the input
[
{
key1: value1, // value1 is an object
key2: value2
},
{
key1: value1, // value1 is also an object
key2: value2
}
]
Solution:
I ended up with,
const testvar = [obj1, obj2, obj3].map((obj) => {
return {
...obj,
key1: new Long.fromValue(obj.key1)
}
});
console.log(testvar);
Which gives the output
[
{
key1: value1, // value1 is now a Long object
key2: value2
},
{
key1: value1, // value1 is also now a Long object
key2: value2
}
]
Below are 2 objects what I want is Object.assign(initalPlan, data), but I want to delete the fields also that are not provided in data.
const initialPlan = {
default_plan: false,
external_plan_id: fakeString,
public_available: true,
name: fakeString,
price: fakeNumber,
pricing_period: fakeNumber,
pricing_period_unit: fakeString,
space_limit: fakeNumber,
staff_max_limit: fakeNumber,
staff_min_limit: fakeNumber,
trial_period: fakeNumber,
trial_period_unit: fakeString,
};
and other object:
const data = {
external_plan_id: plan.external_plan_id,
space_limit: plan.space_limit,
staff_min_limit: plan.staff_min_limit,
staff_max_limit: plan.staff_max_limit,
file_storage_limit: plan.file_storage_limit,
file_storage_limit_unit: plan.file_storage_limit_unit,
default_plan: plan.default_plan,
};
Any ideas?
After you have your data and initialPlan objects, you can do something like this to remove the properties on initialPlan that aren't present on data. Then you could use Object.assign(initialPlan, data).
const dataKeys = Object.keys(data);
const initialPlanKeys = Object.keys(initialPlan);
initialPlanKeys.forEach(k => {
if (!dataKeys.includes(k))
delete initialPlan[k];
});
You should use Object.assign and remove all the keys that are not part of data
const initialPlan = {
key1: 1,
key2: 2,
key3: 3
}
const data = {
key1: 10,
key2: 0
}
Object.assign(initialPlan, data);
Object.keys(initialPlan).forEach(function(key){
if(!data.hasOwnProperty(key)) delete initialPlan[key];
});
console.log(initialPlan)