This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 3 years ago.
I'm writing a simple Vue app where an Array with Objects should be updated with an incoming object.
I start with this Object:
var arr =
[
{
"mainId": 1,
"parents": [
{
"parent": 1
},
{
"parent": 2
}
]
},
{
"mainId": 2,
"parents": [
{
"parent": 3
}
]
}
]
I want to Update the "parent" Array with the following Object:
var updateArray = {
"mainId": 2,
"parent": 9
}
var updatedArray =
[
{
"mainId": 1,
"parents": [
{
"parent": 1
},
{
"parent": 2
}
]
},
{
"mainId": 2,
"parents": [
{
"parent": 3
},
{
"parent": 9 // <-------------
}
]
}
]
What is the best way to achieve this?
You can look for the object using Array.find and it will give you a reference to the object inside the array, so when you update that object, it will be updated inside the array :
var arr = [{
mainId: 1,
parent: [{
parent: 1
},
{
parent: 2
}
]
},
{
mainId: 2,
parent: [{
parent: 3
}]
}
];
var updateArray = {
mainId: 2,
parent: 9
};
var obj = arr.find(o => o.mainId === updateArray.mainId);
obj.parent.push({
parent: updateArray.parent
})
console.log(arr);
You can achieve it by using native map function without any mutations:
const updatedArray = arr.map(obj => {
if (obj.mainId === givenMainId) {
const parent = obj.parent || []
return { ...obj, parent: [...parent, { parent: givenParentId }] };
}
return obj;
})
You can use find() to get the appropriate item by its mainId identifier and then use push() to add another object:
const arr =
[
{
"mainId": 1,
"parent": [
{
"parent": 1
},
{
"parent": 2
}
]
},
{
"mainId": 2,
"parent": [
{
"parent": 3
}
]
}
]
const id = 2
const obj = arr.find(({mainId}) => mainId === id)
obj.parent.push({ "parent": 9 })
console.log(arr)
Related
This question already has answers here:
Group array items using object
(19 answers)
How can I group an array of objects by key?
(32 answers)
Closed 7 months ago.
I want to make this
const arr = [
{
"name": "mac"
},
{
"group": "others",
"name": "lenovo"
},
{
"group": "others",
"name": "samsung"
}
]
into this:
[
{
name: 'mac',
},
{
name: 'others',
group: [
{
name: 'lenovo',
},
{
name: 'samsung',
},
],
}
]
I tried to use normal forEach loop but it didn't turn out well:
let final = []
const result = arr.forEach(o => {
if(o.group) {
group = []
group.push({
name: o.name
})
final.push(group)
} else {
final.push(o)
}
});
Not sure if reduce might help? before I try lodash groupBy I want to use just pure js to try to make it.
Hope this answer will work for you.
const arr = [
{
name: "mac",
},
{
group: "others",
name: "lenovo",
},
{
group: "others",
name: "samsung",
},
];
const temp = [];
arr.forEach((e) => {
if (!e.group) {
temp.push(e);
} else {
const index = temp.findIndex((ele) => ele.name === e.group);
if (index === -1) {
obj = {
name: e.group,
group: [{ name: e.name }],
};
temp.push(obj)
} else {
temp[index].group.push({ name: e.name });
}
}
});
console.log(temp);
instead of creating and pushing group array in final again and again u should just push group in the end of foreach
like this--
let final = []
let group = []
const result = arr.forEach(o => {
if(o.group) {
group.push({
name: o.name
})
} else {
final.push(o)
}
})
final.push({name: "others", group})
This question already has answers here:
Flatten array of objects of arrays JavaScript
(6 answers)
How to do equivalent of LINQ SelectMany() just in javascript
(11 answers)
Merge arrays from object property in an object array [closed]
(3 answers)
Closed 1 year ago.
I know it is probably very simple, but i can't figure it out since 2 days.
{
"users": [
{
"id": 1,
"name": "Example1",
"data": [{data: "data1"}, {data:"data2"}]
},
{
"id": 2,
"name": "Example2",
"data": [{data: "data3"}, {data:"data4"}]
}
]
}
I want to merge all data's arrays into one.
I tried in many ways, for example like this, but it's not what i want.
let arr = [];
users.map(el => {
return arr.push([].concat([...el.data]))
})
console.log(arr)
what i want is that :
arr = [{data: "data1"}, {data:"data2"}, {data: "data3"}, {data:"data4"}]
If someone is able to help me I will be extremely grateful.
You can apply a .flat() at the end:
let obj = {
"users": [
{
"id": 1,
"name": "Example1",
"data": [{data: "data1"}, {data:"data2"}]
},
{
"id": 2,
"name": "Example2",
"data": [{data: "data3"}, {data:"data4"}]
}
]
};
let photos = obj.users.map(({ data }) => [].concat(data)).flat();
console.log(photos);
Just map over the array and use flat on the result.
const obj = {
users: [{
id: 1,
name: "Example1",
data: [{
data: "data1"
}, {
data: "data2"
}],
},
{
id: 2,
name: "Example2",
data: [{
data: "data3"
}, {
data: "data4"
}],
},
],
};
const result = obj.users.map((o) => o.data).flat();
console.log(result);
or just use flatMap
const obj = {
users: [{
id: 1,
name: "Example1",
data: [{
data: "data1"
}, {
data: "data2"
}],
},
{
id: 2,
name: "Example2",
data: [{
data: "data3"
}, {
data: "data4"
}],
},
],
};
const result = obj.users.flatMap((o) => o.data);
console.log(result);
I stacked with trivial question but can't find the solution.
Any help will be appreciated.
I have an array of obects
[
{
id: 1,
title: 'home',
parent: null,
},
{
id: 2,
title: 'about',
parent: null,
},
{
id: 3,
title: 'team',
parent: 2,
},
{
id: 4,
title: 'company',
parent: 2,
},
,
{
id: 5,
title: 'department',
parent: 4,
},
];
To make Tree I use this function:
Solution from here
const treeify = (arr) => {
const tree = [];
const lookup = {};
arr.forEach((o) => {
lookup[o.id] = o;
lookup[o.id].children = [];
});
arr.forEach((o) => {
if (o.parent !== null) {
lookup[o.parent].children.push(o);
} else {
tree.push(o);
}
});
return tree;
};
And finally I have the tree like so:
[
{
"id": 1,
"title": "home",
"parent": null,
"children": []
},
{
"id": 2,
"title": "about",
"parent": null,
"children": [
{
"id": 3,
"title": "team",
"parent": 2,
"children": []
},
{
"id": 4,
"title": "company",
"parent": 2,
"children": [
{
"id": 5,
"title": "department",
"parent": 4,
"children": []
}
]
}
]
}
]
The question is: How replace parent ID with object itself?
I want the result like:
"id": 4,
"title": "company",
"parent": { // <-- how to change just id to object here
"id": 2,
"title": "about",
"parent": null,
},
"children": []
Thank you for help!
You could take a single loop approach with a reference for each found node.
const
data = [{ id: 1, title: 'home', parent: null, }, { id: 2, title: 'about', parent: null }, { id: 3, title: 'team', parent: 2 }, { id: 4, title: 'company', parent: 2 }, { id: 5, title: 'department', parent: 4 }],
tree = function (data, root) {
var t = {};
data.forEach(o => {
Object.assign(t[o.id] = t[o.id] || {}, o);
t[o.parent] = t[o.parent] || {};
t[o.parent].children = t[o.parent].children || [];
t[o.parent].children.push(t[o.id]);
if (t[o.id].parent !== null) t[o.id].parent = t[t[o.id].parent];
});
return t[root].children;
}(data, null);
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could use reduce method to create recursive function and pass parentId and parent object to the nested recursive calls. And if there is parent object you assign it to current element.
const data = [{"id":1,"title":"home","parent":null},{"id":2,"title":"about","parent":null},{"id":3,"title":"team","parent":2},{"id":4,"title":"company","parent":2},{"id":5,"title":"department","parent":4}]
const treeify = (data, pid = null, parent = null) => {
return data.reduce((r, e) => {
if (e.parent === pid) {
const o = { ...e }
if (parent) o.parent = parent;
const children = treeify(data, e.id, e);
if (children.length) o.children = children;
r.push(o)
}
return r;
}, [])
}
const result = treeify(data);
console.log(JSON.stringify(result, 0, 4))
I have an array of objects like this:
myArr = [
{ "id": "aaa.bbb" },
{ "id": "aaa.ccc" },
{ "id": "111.222" },
{ "id": "111.333" },
]
My goal is to be able to have a new array for every part of the Id, while nesting the old array. Like this:
newArray = [
{
"id": "aaa",
"children": [{ "id": "aaa.bbb" }]
},
{
"id": "aaa",
"children": [{ "id": "aaa.ccc" }]
},
{...}
]
The idea is to be able to do It with multiple substrings if there is a bigger Id
You could use map to iterate through the array and mutate the objects in place
myArr = [ { "id": "aaa.bbb" }, { "id": "aaa.ccc" }, { "id": "111.222" }, { "id": "111.333" }, ]
result=myArr.map((o)=>({["id"]:o.id.split(".")[0],["children"]:[o]}))
console.log(result)
alternatively you could use reduce
myArr = [ { "id": "aaa.bbb" }, { "id": "aaa.ccc" }, { "id": "111.222" }, { "id": "111.333" }, ]
result=myArr.reduce((acc,curr)=>acc=[...acc,{["id"]:curr.id.split(".")[0],["children"]:[curr]}],[])
console.log(result)
Use Array.prototype.map.
const newArray = myArr.map( function( e ) {
const oldId = e.id;
const newElement = {
id: oldId.split( '.' )[0],
children: [ e ]
};
return newElement
} );
Simplified:
const newArray = myArr.map( function( e ) {
return {
id: e.id.split( '.' )[0],
children: [ e ]
};
} );
Further:
const newArray = myArr.map( e => { id: e.id.split( '.' )[0], children: [ e ] } );
I have two JSON arrays, would like to know the key which don't match. I don't need the value.
Example:
livetable: [
{ id: 1, name: "Sandra" },
{ id: 2, name: "John" },
],
backupTable: [
{ id: 1, name: "Sandra" },
{ id: 2, name: "Peter" },
],
I can get the key/value pair which is diffrent with this Lodash script:
difference = _.differenceWith(livetable,backupTable,_.isEqual)
But I would just need the key, in this example "name" for "id: 2" is not matching, so I would need to get the "name" key to new array/variable.
(Using VUE CLI)
EDIT: Added example of current code output.
var livetable = [{"id": 1, "name": "Sandra", "id": 2, "name": "John"}]
var backupTable = [{"id": 1, "name": "Sandra", "id": 2, "name": "Peter"}]
console.log(_.differenceWith(backupTable,livetable,_.isEqual))
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.15/lodash.min.js"></script>
This will output the key:value pair, but I would just need the key which is diffrent.
I think I understand what you're trying to do. There are some unknowns though, like what should happen if there is a missing record in the second data set?
This solution assumes each table of data has the same amount of records and the records have the same IDs.
// define data
const livetable = [
{ id: 1, name: "Sandra" },
{ id: 2, name: "John" }
]
const backupTable = [
{ id: 1, name: "Sandra" },
{ id: 2, name: "Peter" }
]
const getDifferentRecordsByID = (sourceRecords, compareRecords) => {
// simple utility function to return a record object matching by ID
const findComparisionRecord = id => compareRecords.find(compareRecord => compareRecord.id === id)
// using the utility function, we can filter out any mismatching records by comparing name
return sourceRecords
.filter(sourceRecord => sourceRecord.name !== findComparisionRecord(sourceRecord.id).name)
// then map over all the records and just pull out the ID
.map(record => record.id)
}
console.log(getDifferentRecordsByID(livetable, backupTable)) // [2]
Here is working VUE code for my problem.
Function returns [ "name" ], which is exactly what I need.
data() {
return {
livetable: [{ id: 1, name: "Sandra" },{ id: 2, name: "John" }],
backupTable: [{ id: 1, name: "Sandra" },{ id: 2, name: "Peter" }],
difColumns: null,
};
},
methods: {
test3() {
let resultArray = []
this.livetable.forEach((array1, index) => {
const array2 = this.backupTable[index];
resultArray.push(this._.reduce(array1, (result, value, key) => this._.isEqual(value, array2[key]) ? result : result.concat(key), []))
});
this.difColumns = resultArray[0]
}
},