Updating an array of objects without mutation - javascript

If I have an object:
[
{
"value":"d1",
"label":"bathstore.com",
"selected":true
},
{
"value":"d2",
"label":"superdrug.com",
"selected":true
},
{
"value":"d3",
"label":"papajohns.com",
"selected":true
}
]
how can I change every value of 'selected' field to 'false' using spread operator or Object.assign() to avoid object mutation?

You can iterate over array with map and inside each callback use spread syntax to create new objects with updated property:
let data = [
{
"value":"d1",
"label":"bathstore.com",
"selected":true
},
{
"value":"d2",
"label":"superdrug.com",
"selected":true
},
{
"value":"d3",
"label":"papajohns.com",
"selected":true
}
];
let newData = data.map((item) => {
return {...item, selected: false};
});
console.log(newData);

Related

Loop through array of objects and assign parent object to each child array of object using javascript

I have an array of object as follows. Currently there is only one object but invocations has an array of objects.
Depending on how many array of objects we have for invocations, we want to update the main array of objects. For e.g. if there are 2 objects in invocations, i want to separate those 2 invocations and replicate their parent object for both invocations.
This is not a regular iteration of array of objects and thats why i am not able to get the desired result. Any help is appreciated
const input = [
{
"name": "Test Data",
"invocations": [
{ "invocationId": "123" },
{ "invocationId": "125" },
]
},
]
const output = [
{
"name": "Test Data",
"invocations": [
{ "invocationId": "123" },
]
},
{
"name": "Test Data",
"invocations": [
{ "invocationId": "125" },
]
}
]
Here is a working example non-one-liner though!
For each object inside your array, you loop through the invocations property array and push each object inside a temp array along with all the other properties.
Then this array is concatenated with the final array.
const input = [
{
"name": "Test Data",
"invocations": [
{ "invocationId": "123" },
{ "invocationId": "125" },
]
},
]
let finalArray = []
Object.values(input).forEach(obj => {
let arr = []
obj.invocations.forEach(invoc => arr.push({...obj, invocations: [ invoc ]}))
finalArray = finalArray.concat(arr)
});
console.log(finalArray)
This will do it:
const splitInvocations = array => {
return array.reduce((result, obj) => {
const parentAssignedObjects = obj.invocations.map(invocation => ({ ...obj, invocations: [invocation] }));
return [...result, ...parentAssignedObjects];
}, []);
};
First, we loop through the array with reduce. We then map each invocation and return the parent object with a replaced value for the property invocations. We concat the reduce accumulator with the output of map using spread syntax.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

How to update an array of objects with data taken from the corresponding elements of another same-size array?

Say I have an array of objects as follows:
data = [
{
"id":34
},
{
"id":35
},
{
"id":36
},
{
"id":37
}
]
and another array as follows:
myNumberArray = [1,2,3,4]
They might be much larger, but the number of elements in both arrays will always be the same. I want to modify each element of data by adding a number attribute, assigning it the value from the corresponding element of myNumberArray.
When done, data will look as follows:
data = [
{
"number":1,
"id":34
},
{
"number":2,
"id":35
},
{
"number":3,
"id":36
},
{
"number":4,
"id":37
}
]
How can I do this?
myNumberArray = [1,2,3,4]
data = [
{
"id":34
},
{
"id":35
},
{
"id":36
},
{
"id":37
}
]
data.forEach((elem, index)=>{
data[index]["number"]=myNumberArray[index];
})
console.log(data);
This should solve your problem.
Explanation:
I used forEach to iterate over the data array, forEach accepts two parameters, the current value at an index, and the value.
Since, yours is a one-to-one mapping, we are using the current index to access the value at the same index in myNumberArray and assigning that new value in data for number key.
Try the following solution:
let myNumberArray = [1,2,3,4];
let data = [
{
"id":34
},
{
"id":35
},
{
"id":36
},
{
"id":37
}
];
const updatedArray = data.map((item,index)=> {
return {
...item,
"number":myNumberArray[index]
}
});
console.log(updatedArray);
let myNumberArray = [1,2,3,4]
let data = [
{
"id":34
},
{
"id":35
},
{
"id":36
},
{
"id":37
}
]
data = data.map( (x, i) => ({ number: myNumberArray[i], id: x.id}) )
console.log(data)
for (let i in myNumberArray) {
Object.assign(data[i], {
number: myNumberArray[i]
})
}

Typescript flatten complex nested array

I'm still pretty new to Typescript so I've been looking at all the provided solutions but I'm still stuck with a complex nested array. I have the following structure:
data = [{
"property1_1": "value1_1",
"property1_2": "value1_2",
"property1_3": [
[{
"subproperty1_1_1": "subvalue1_1_1",
"subproperty1_1_2": "subvalue1_1_2"
}],
[{
"subproperty1_2_1": "subvalue1_2_1",
"subproperty1_2_2": "subvalue1_2_2"
}]
]
},
{
"property2_1": "value2_1",
"property2_2": "value2_2",
"property2_3": [
[{
"subproperty2_2_1": "subvalue2_2_1",
"subproperty2_2_2": "subvalue2_2_2"
}],
[{
"subproperty2_2_1": "subvalue2_2_1",
"subproperty2_2_2": "subvalue2_2_2"
}]
]
}
]
and I would like to achieve a simple array with objects looking like:
data = [{
"property1_1": "value1_1",
"property1_2": "value1_2",
"subproperty1_1_1": "subvalue1_1_1",
"subproperty1_1_2": "subvalue1_1_2",
"subproperty1_2_1": "subvalue1_2_1",
"subproperty1_2_2": "subvalue1_2_2"
},
{
"property2_1": "value2_1",
"property2_2": "value2_2",
"subproperty2_1_1": "subvalue2_1_1",
"subproperty2_1_2": "subvalue2_1_2",
"subproperty2_2_1": "subvalue2_2_1",
"subproperty2_2_2": "subvalue2_2_2"
}
]
I've already achieved to collect the subproperties into one array like doing:
const allDataConv = [];
data.forEach(dateninput => {
dateninput.propertyname.forEach(item => {
item.forEach(lastitem => {
allDataConv.push({key: lastitem.description, title: lastitem.name});
});
});
});
return allDataConv;
But that's not what I want to achieve. I'm stuck with the question: How can I apply the double nested objects into the corresponding parent object?
You could iterate over your object keys and check if the value is an array. If it's an array use flat(1) to flatten it and then iterate over it's children. Use Object.assign to add the child object keys to your root object and delete the key which had the array as a value.
Array.flat is an ESNext feature, you may need a polyfill for it in older browsers or use another for-of loop.
const input = data = [
{
"property1_1": "value1_1",
"property1_2": "value1_2",
"property1_3": [
[
{
"subproperty1_1_1": "subvalue1_1_1",
"subproperty1_1_2": "subvalue1_1_2"
}
],
[
{
"subproperty1_2_1": "subvalue1_2_1",
"subproperty1_2_2": "subvalue1_2_2"
}
],
],
},
{
"property2_1": "value2_1",
"property2_2": "value2_2",
"property2_3": [
[
{
"subproperty2_1_1": "subvalue2_2_1",
"subproperty2_1_2": "subvalue2_2_2"
}
],
[
{
"subproperty2_2_1": "subvalue2_2_1",
"subproperty2_2_2": "subvalue2_2_2"
}
]
]
}
];
function transformData(input) {
return input.map(obj => {
for(const prop in obj) {
if(obj.hasOwnProperty(prop) && Array.isArray(obj[prop])) {
for(const subObj of obj[prop].flat(1)) {
Object.assign(obj, subObj);
delete obj[prop];
}
}
}
return obj;
})
}
console.log(transformData(input));

React: set the state based on array values

I have an array of questions like this
[
{
title: 'what_are_your_hobbies',
},
{
title: 'do_you_know_german',
},
]
how can I iterate over this array and set its titles to the state like:
state = {
what_are_your_hobbies: '',
do_you_know_german: ''
}
You could use reduce to iterate over the array and set all title to a key on the new object and use that to update your state.
Example
const arr = [
{
title: "what_are_your_hobbies"
},
{
title: "do_you_know_german"
}
];
const stateUpdate = arr.reduce((result, element) => {
result[element.title] = "";
return result;
}, {});
this.setState(stateUpdate);

changing an array element of json in array is changing the rest json array elements in angular2

this is the array variable
let packageitems=
[
{
"packageid":1,
"items":[
{
"itemid":"1",
"name":"abc"
},
{
"itemid":"2",
"name":"cdr"
}
]
},
{
"packageid":2,
"items":[
{
"itemid":"1",
"name":"abc"
},
{
"itemid":"2",
"name":"xyz"
}
]
}
]
in angular typescript i am having one function:
updatePackageitem(newitem){
let objIndex = this.packageitems.findIndex(obj => obj.packageid==newitem.packageid);
Object.assign(this.packageitems[objIndex] , newitem);
}
newitem json is similar just the items array is different
when i assign using Object.assign the newitem array elements get copies to all rest json of this.packageitems even after getting the objIndex right
newitem =
{
"packageid":2,
"items":[
{
"itemid":"1",
"name":"def"
},
{
"itemid":"2",
"name":"pqr"
}
]
}

Categories

Resources