Can anyone help me in merging of two array of objects please using loadash in javascript? Below is the example arrays. I tried with _merge
arr 1= [
{
"areaId": 1,
"areaName": "areanam222",
"businessExecutiveId": 1
},
{
"areaId": 2,
"areaName": "arename",
"businessExecutiveId": 1
}
]
arr2 =[
{
"id": 1,
"name": "BN",
}
]
arrResult =[
{
"areaId": 1,
"areaName": "areanam222",
"businessExecutiveId": 1,
"id": 1,
"name": "BN"
}, {
"areaId": 2,
"areaName": "arename",
"businessExecutiveId": 1,
"id": 1,
"name": "BN"
}
]
I tried with below option but it is returning only one record.
var arrResult = _(list).keyBy('businessExecutiveId').merge(_.keyBy(this.typeaheadDataList, 'id')).values() .value();
I also tried with below
const c = _.assign([], arr1, arr2);
reslut I am getting is like below
{
id: 1,
name: "BN"
},
{
areaId: 1,
areaName: "ASas",
businessExecutiveId: 1,
id: 1,
name: "BN"
}
Please help me
You don't need lodash to do this. Why not just use javascripts reduce function to merge all object keys from arr2 objects into the objects of array 1, like so
arr1.reduce((arr, obj) => {
const newObj = arr2.reduce((o, insideObj) => ({
...o,
...insideObj
}), obj)
return [...arr, newObj]
}, [])
arr1.reduce((arr, obj) => {
const newObj = arr2.reduce((o, insideObj) => ({
...o,
...insideObj
}), obj)
return [...arr, newObj]
}, [])
I resolved it by using below code.
_.map(list, function(item) {
return _.merge(item, _.find(temp, function(o) {return o.id == item.businessExecutiveId }) );
});
If we had array comprehension, we could have used something like this:
[
for (a of arr1)
for (b of arr2)
if(a.businessExecutiveId === b.id) {...a, ...b}
]
Without array comprehension, we use flatMap:
_(arr1).flatMap(a =>
_(arr2).flatMap(b =>
a.businessExecutiveId === b.id ? [{...a, ...b}] : []
).value()
).value()
var arr1= [
{
"areaId": 1,
"areaName": "areanam222",
"businessExecutiveId": 1
},
{
"areaId": 2,
"areaName": "arename",
"businessExecutiveId": 1
},
{
"areaId": 3,
"areaName": "bname",
"businessExecutiveId": 2
}
]
var arr2= [
{
"id": 1,
"name": "BN",
},
{
"id": 2,
"name": "CM",
}
]
res = _(arr1).flatMap(a =>
_(arr2).flatMap(b =>
a.businessExecutiveId === b.id ? [{...a, ...b}] : []
).value()
).value()
console.log(res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Related
I have an array of objects:
const workouts = [
{
id: 1,
name: "Bench Press",
superset_id: 1,
},
{
id: 2,
name: "Squats",
superset_id: 2,
},
{
id: 3,
name: "Shoulder Press",
superset_id: 1,
},
{
id: 4,
name: "Leg Press",
superset_id: 2,
},
...
];
What I would like to do is filter the array for objects with a matching superset_id and return a new array that looks like this:
[
[
{
id: 1,
name: "Bench Press",
superset_id: 1,
},
{
id: 3,
name: "Shoulder Press",
superset_id: 1,
},
],
[
{
id: 2,
name: "Squats",
superset_id: 2,
},
{
id: 4,
name: "Leg Press",
superset_id: 2,
},
],
...
];
How can I achieve this?
Use a combination of Math.max() and .map() to find the largest superset_id in the data, then filter the data for every superset_id. Like this:
const data = [{id:1,name:"Bench Press",superset_id:1},{id:2,name:"Squats",superset_id:2},{id:3,name:"Shoulder Press",superset_id:1},{id:4,name:"Leg Press",superset_id:2},];
const maxSuperset = Math.max(...data.map(el => el.superset_id));
const res = [];
for (let i = 1; i <= maxSuperset; i++) {
res.push(data.filter(el => el.superset_id === i));
}
console.log(res)
You can use Array#reduce with an object to store the values for each id.
const workouts=[{id:1,name:"Bench Press",superset_id:1},{id:2,name:"Squats",superset_id:2},{id:3,name:"Shoulder Press",superset_id:1},{id:4,name:"Leg Press",superset_id:2},];
let res = Object.values(
workouts.reduce((acc, curr) => {
(acc[curr.superset_id] ??= []).push(curr);
return acc;
}, {})
);
console.log(res);
As long as superset_id is incremental, this might be an idea.
const newArray = [];
array.forEach((elem) => {
if(newArray[elem.superset_id - 1] === undefined) {
newArray[elem.superset_id - 1] = [];
}
newArray[elem.superset_id - 1].push(elem);
});
I need to transform this structure:
[
{"Field1": "value11", "Field2":"value21", "CField1":[{"Id": 1, "Value":"myValue11", "Flag":"Y"}, {"Id": 2, "Value":"myValue12", "Flag":"n"}]},
{"Field1": "value21", "Field2":"value22", "CField1":[{"Id": 1, "Value":"myValue21", "Flag":"Y"}, {"Id": 2, "Value":"myValue22", "Flag":"n"}]}
]
to
[
{"Field1": "value11", "Field2":"value12", "Value1": "myValue11", "Flag1":"Y", "Value2": "myValue12", "Flag2":"n"},
{"Field1": "value21", "Field2":"value21", "Value1": "myValue21", "Flag1":"Y", "Value2": "myValue22", "Flag2":"n"},
]
i found that similar solution:
tab.forEach(function (item) {
transformedObject[item.key] = transformedObject[item.key] ? `${transformedObject[item.key]}, ${item.value}` : item.value;
});
console.log(transformedObject);
// Access the '2' property
console.log(transformedObject['2']);
but need some help to adapt it to my case
thanks
You could map the inner array as new objects.
const
data = [{ Field1: "value11", Field2: "value21", CField1: [{ Id: 1, Value: "myValue11", Flag: "Y" }, { Id: 2, Value: "myValue12", Flag: "n" }] }, { Field1: "value21", Field2: "value22", CField1: [{ Id: 1, Value: "myValue21", Flag: "Y" }, { Id: 2, Value: "myValue22", Flag: "n" }] }],
result = data.map(({ CField1, ...o }) => Object.assign(
o,
...CField1.map(({ Id, ...q }, i) => Object.fromEntries(Object
.entries(q)
.map(([k, v]) => [k + (i + 1), v])
))
));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can map your data like this:
data = [
{"Field1": "value11", "Field2":"value21", "CField1":[{"Id": 1, "Value":"myValue11", "Flag":"Y"}, {"Id": 2, "Value":"myValue12", "Flag":"n"}]},
{"Field1": "value21", "Field2":"value22", "CField1":[{"Id": 1, "Value":"myValue21", "Flag":"Y"}, {"Id": 2, "Value":"myValue22", "Flag":"n"}]}
]
console.log(data.map(function(value, key) {
return Object.entries(value).reduce(function(carry, [ key, value ]) {
if (key !== 'CField1') {
carry[key] = value
} else {
carry = Object.assign(carry, value.reduce(function(innerCarry, value, key) {
innerCarry[`Flag${value.Id}`] = value.Flag
innerCarry[`Value${value.Id}`] = value.Value
return innerCarry;
}, {}))
}
return carry
}, {})
}))
I have this array which holds objects;
let arr = [
{
"id": 1,
"level": "2",
},
{
"id": 2,
"level": "3",
}
]
By default the array has keys starting from 0 and it looks like this:
[
0: {id: 1, level:2},
1: {id: 2, level:3}
]
How can I transform it so that the keys are the values of the property 'level'?
It should look like this:
[
2: {id:1, level:2},
3: {id:1, level:3}
]
So far I have tried this but it doesn't remove the original keys:
arr.map((v, k) => ({[v.level]: v}));
So I have something like this:
[
0: {2:
{id: 1, level:2}
},
1: {3:
{id: 2, level:3}
}
]
You need to populate a new array using reduce:
arr.reduce((prev, curr) => { prev[curr.level] = curr; return prev }, [])
I think I prefer the reduce method, but you could also construct an "array-like" (i.e. an object with numeric keys and a length property) and pass it to Array.from
const maxIdx = Math.max(...arr.map(v => parseInt(v.level, 10)))
const arrLen = maxIdx + 1;
const arrayLike = {
...Object.fromEntries(arr.map(v => [v.level, v])),
length: arrLen
};
const mappedArray = Array.from(arrayLike);
For output of
[undefined, undefined, {
"id": 1,
"level": "2"
}, {
"id": 2,
"level": "3"
}]
I want to restructure the current JSON of data as shown below
const data = [
{
"status": "Complete",
"totalToday": 3,
"weekly": 20
},
{
"status": "Pending",
"totalToday": 5,
"weekly": 13
},
{
"status": "Rejected",
"totalToday": 2,
"weekly": 5
}
];
Expected output:
const newData = [
['Status', 'Total Today', 'Weekly'],
['Complete', 3, 20],
['Pending', 5, 13],
['Rejected', 2, 5]
];
You can use Array.forEach()
const data = [{
"status": "Complete",
"totalToday": 3,
"weekly": 20
},
{
"status": "Pending",
"totalToday": 5,
"weekly": 13
},
{
"status": "Rejected",
"totalToday": 2,
"weekly": 5
}
];
let transformedData = []
transformedData.push(Object.keys(data[0]).map(key => {
return key.replace(/([A-Z])/g, ' $1')
.replace(/^./, (str) => str.toUpperCase())
}))
data.forEach(val => transformedData.push(Object.values(val)))
console.log(transformedData)
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}
You can simply use a reduce method, in which you iterate over an Array of Object. On the 0 index, you can use Object.keys() to get the key and Object.values for the corresponding values and push it to the accumulator. For else you can iterate Object values and push it to the accumulator acc.
const data = [
{
"status": "Complete",
"totalToday": 3,
"weekly": 20
},
{
"status": "Pending",
"totalToday": 5,
"weekly": 13
},
{
"status": "Rejected",
"totalToday": 2,
"weekly": 5
}
];
const newData = data.reduce((acc, x, idx) => {
if(idx === 0) {
acc.push(Object.keys(x), Object.values(x));
} else {
acc.push(Object.values(x));
}
return acc;
}, [])
console.log(newData);
I got the following array:
var arr = [{
"mainId": 1,
"parents": [{
"parent": 1
},
{
"parent": 2
}
]
},
{
"mainId": 2,
"parents": [{
"parent": 3
}]
}
]
I'm using this function to delete an specific parent in the parents array
var idToDelete = 2
arr.forEach(function (o) {
o.parents = o.parents.filter(s => s.id !== idToDelete
})
This is working fine. But when idToDelete = 3 I want to delete the complete main Item and start a function "startSomething"
So that I'm left with the following output
var arr = [{
"mainId": 1,
"parents": [{
"parent": 1
},
{
"parent": 2
}
]
}]
How could this be implemented?
You can map and then filter the top level array, here is an example:
var arr = [{
"mainId": 1,
"parents": [{
"parent": 1
},
{
"parent": 2
}
]
},
{
"mainId": 2,
"parents": [{
"parent": 3
}]
}
];
var idToDelete = 3;
arr = arr.map((v) => ({
...v,
parents: v.parents.filter(({
parent
}) => parent !== idToDelete)
}))
.filter((v) => v.parents.length);
console.log(arr);
Filter the parent array by whether it has a .length after mutating the children. Also make sure to use the .parent property (your objects have no .id property):
const startSomething = () => console.log('startSomething');
var arr =
[
{
"mainId": 1,
"parents": [
{
"parent": 1
},
{
"parent": 2
}
]
},
{
"mainId": 2,
"parents": [
{
"parent": 3
}
]
}
];
var idToDelete = 3;
arr.forEach(function (o) {
o.parents = o.parents.filter(s => s.parent !== idToDelete)
});
const newArr = arr.filter(({ parents }) => parents.length);
console.log(newArr);
if (newArr.length !== arr.length) {
startSomething();
}
You can use .filter() on the array itself (to remove the main object) with .some() to return true or false depending on whether it should be deleted or not:
const arr = [{ "mainId": 1, "parents": [{ "parent": 1 }, { "parent": 2 } ] }, { "mainId": 2, "parents": [{ "parent": 3 }] } ];
const removeObj = (arr, id, cb) => {
const res = arr.filter(({parents}) => !parents.some(({parent}) => parent === id));
const item_removed = res.length !== arr.length;
return (item_removed && cb(res), item_removed);
}
const startSomething = new_arr => console.log("Starting with arr", new_arr);
removeObj(arr, 3, startSomething);
.as-console-wrapper { max-height: 100% !important;} /* ignore */
Here's a alternative method, with a function that uses findIndex to find the object in the array.
Then splices the object if it only has 1 parent.
Or splices the parent from object if it has more than 1 parent.
Example snippet:
const deleteParent = (arr, id) =>
{
let idx = arr.findIndex(x=>x.parents.some(p=> p.parent === id));
if (idx >= 0 && arr[idx].parents.length === 1 ) {
let obj = arr[idx];
// remove object from array and do something
arr.splice(idx, 1);
doSomething(obj);
}
else if(idx >= 0){
let obj = arr[idx];
let parentIdx = obj.parents.findIndex(x=>x.parent==id);
// remove parent
obj.parents.splice( parentIdx, 1);
}
}
function doSomething (obj) { console.log(`Deleted mainId ${obj.mainId}`) }
var arr = [
{
"mainId": 1,
"parents": [
{
"parent": 1
},
{
"parent": 2
}
]
},
{
"mainId": 2,
"parents": [
{
"parent": 3
}
]
}
];
deleteParent(arr, 3);
console.log(JSON.stringify(arr));
deleteParent(arr, 2);
console.log(JSON.stringify(arr));