Merge Objects in a array and increase count - javascript

[{name:"abc",value:5},{name:"abc",value:10},{name:"abc1",value:5},{name:"abc1",value:15}]
I want to merge it by name so that the new array will be
[{name:"abc",value:15},{name:"abc1",value:20}]
Can i do it with es6 or a simple function

Using reduce and without find or findIndex
const data = [{name:"abc",value:5},{name:"abc",value:10},{name:"abc1",value:5},{name:"abc1",value:15}];
const summedDataObj = data.reduce((acc, entry) => {
if (acc[entry.name]) acc[entry.name].value += entry.value;
else acc[entry.name] = entry;
return acc;
}, {});
const summedDataArr = Object.values(summedDataObj);
console.log(summedDataArr);

We can do it via Array.reduce()
let data = [{name:"abc",value:5},{name:"abc",value:10},{name:"abc1",value:5},{name:"abc1",value:15}]
let result = data.reduce((a,{name,value}) => {
let obj = a.find(e => e.name === name)
if(obj){
obj.value += value
}else{
a.push({name,value})
}
return a
},[])
console.log(result)

you can group the data by name using this function:
function groupBy(arr, prop) {
const map = new Map(Array.from(arr, obj => [obj[prop], []]));
arr.forEach(obj => map.get(obj[prop]).push(obj));
return Array.from(map.values());
}
this yields this result:
[
[
{"name": "abc", "value": 5},
{"name": "abc", "value": 10}
],
[
{"name": "abc1", "value": 5},
{"name": "abc1", "value": 15}
]
]
which can be aggregated by using reduce on each resulting array:
groupedData.map(entry=>entry.reduce((acc,cur)=>({
...acc,
value: acc.value + cur.value
})))
so all together we get:
function groupBy(arr, prop) {
const map = new Map(Array.from(arr, obj => [obj[prop], []]));
arr.forEach(obj => map.get(obj[prop]).push(obj));
return Array.from(map.values());
}
const data = [{name:"abc",value:5},{name:"abc",value:10},{name:"abc1",value:5},{name:"abc1",value:15}]
const aggregatedData = groupBy(data,"name")
.map(entry=>entry.reduce((acc,cur)=>({
...acc,
value:acc.value+cur.value
})))

const obj = [{name:"abc",value:5},{name:"abc",value:10},{name:"abc1",value:5},{name:"abc1",value:15}]
arr = obj.reduce((obj, item) => {
let find = obj.find(i => i.name === item.name && i.date === item.date);
let _d = {
...item
}
find ? (find.value += item.value ) : obj.push(_d);
return obj;
}, [])
console.log(arr);

const data = [{
name: "abc",
value: 5
},
{
name: "abc",
value: 10
},
{
name: "abc1",
value: 5
},
{
name: "abc1",
value: 15
},
];
const groupArr = data.reduce((r, a) => {
const idx = r.findIndex((el) => el.name === a.name);
idx === -1 ? r.push(a) : (r[idx].value += a.value);
return r;
}, []);
console.log(groupArr);

You can achieve this with the help of Array#reduce method.
Live Demo :
const arr = [{name:"abc",value:5},{name:"abc",value:10},{name:"abc1",value:5},{name:"abc1",value:15}];
const res = arr.reduce((obj, curr) => {
if (obj.hasOwnProperty(curr.name) && obj[curr.name].name === curr.name) {
obj[curr.name].value += curr.value
} else {
obj[curr.name] = curr;
}
return obj
}, {});
console.log(Object.values(res));

Related

Flatten nested JSON to array of unique objects without indexes

I have this simple nested object which I need to flatten to be able to insert it into my database.
const input = {
name: "Benny",
department: {
section: "Technical",
branch: {
timezone: "UTC",
},
},
company: [
{
name: "SAP",
customers: ["Ford-1", "Nestle-1"],
},
{
name: "SAP",
customers: ["Ford-2", "Nestle-2"],
},
],
};
The desired result is like this, each value in the arrays results in a new sub-object stored in an array:
[
{
name: "Benny",
"department.section": "Technical",
"department.branch.timezone": "UTC",
"company.name": "SAP",
"company.customers": "Ford-1",
},
{
name: "Benny",
"department.section": "Technical",
"department.branch.timezone": "UTC",
"company.name": "SAP",
"company.customers": "Nestle-1",
},
{
name: "Benny",
"department.section": "Technical",
"department.branch.timezone": "UTC",
"company.name": "SAP",
"company.customers": "Ford-2",
},
{
name: "Benny",
"department.section": "Technical",
"department.branch.timezone": "UTC",
"company.name": "SAP",
"company.customers": "Nestle-2",
},
]
Instead of the result below which all fields stored in single object with indexes:
{
name: 'Benny',
'department.section': 'Technical',
'department.branch.timezone': 'UTC',
'company.0.name': 'SAP',
'company.0.customers.0': 'Ford-1',
'company.0.customers.1': 'Nestle-1',
'company.1.name': 'SAP',
'company.1.customers.0': 'Ford-2',
'company.1.customers.1': 'Nestle-2'
}
My code looks like this:
function flatten(obj) {
let keys = {};
for (let i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (typeof obj[i] == "object") {
let flatObj = flatten(obj[i]);
for (let j in flatObj) {
if (!flatObj.hasOwnProperty(j)) continue;
keys[i + "." + j] = flatObj[j];
}
} else {
keys[i] = obj[i];
}
}
return keys;
}
Thanks in advance!
You could take the array's values as part of a cartesian product and get finally flat objects.
const
getArray = v => Array.isArray(v) ? v : [v],
isObject = v => v && typeof v === 'object',
getCartesian = object => Object.entries(object).reduce((r, [k, v]) => r.flatMap(s =>
getArray(v).flatMap(w =>
(isObject(w) ? getCartesian(w) : [w]).map(x => ({ ...s, [k]: x }))
)
), [{}]),
getFlat = o => Object.entries(o).flatMap(([k, v]) => isObject(v)
? getFlat(v).map(([l, v]) => [`${k}.${l}`, v])
: [[k, v]]
),
input = { name: "Benny", department: { section: "Technical", branch: { timezone: "UTC" } }, company: [{ name: "SAP", customers: ["Ford-1", "Nestle-1"] }, { name: "SAP", customers: ["Ford-2", "Nestle-2"] }] },
result = getCartesian(input).map(o => Object.fromEntries(getFlat(o)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Edit
In the code below, I left your flatten functionality the same. I added a fix method that converts your original output into your desired output.
Note: I changed the name value of second company to FOO.
const flatten = (obj) => {
let keys = {};
for (let i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (typeof obj[i] == 'object') {
let flatObj = flatten(obj[i]);
for (let j in flatObj) {
if (!flatObj.hasOwnProperty(j)) continue;
keys[i + '.' + j] = flatObj[j];
}
} else {
keys[i] = obj[i];
}
}
return keys;
};
const parseKey = (key) => [...key.matchAll(/(\w+)\.(\d)(?=\.?)/g)]
.map(([match, key, index]) => ({ key, index }));
const fix = (obj) => {
const results = [];
Object.keys(obj).forEach((key) => {
const pairs = parseKey(key);
if (pairs.length > 1) {
const result = {};
Object.keys(obj).forEach((subKey) => {
const subPairs = parseKey(subKey);
let replacerKey;
if (subPairs.length < 1) {
replacerKey = subKey;
} else {
if (
subPairs.length === 1 &&
subPairs[0].index === pairs[0].index
) {
replacerKey = subKey
.replace(`\.${subPairs[0].index}`, '');
}
if (
subPairs.length === 2 &&
subPairs[0].index === pairs[0].index &&
subPairs[1].index === pairs[1].index
) {
replacerKey = subKey
.replace(`\.${subPairs[0].index}`, '')
.replace(`\.${subPairs[1].index}`, '');
result[replacerKey] = obj[subKey];
}
}
if (replacerKey) {
result[replacerKey] = obj[subKey];
}
});
results.push(result);
}
});
return results;
};
const input = {
name: "Benny",
department: { section: "Technical", branch: { timezone: "UTC" } },
company: [
{ name: "SAP", customers: ["Ford-1", "Nestle-1"] },
{ name: "FOO", customers: ["Ford-2", "Nestle-2"] },
]
};
const flat = flatten(input);
console.log(JSON.stringify(fix(flat), null, 2));
.as-console-wrapper { top: 0; max-height: 100% !important; }
Original response
The closest (legitimate) I could get to your desired result is:
[
{
"name": "Benny",
"department.section": "Technical",
"department.branch.timezone": "UTC",
"company.name": "SAP",
"company.customers.0": "Ford-1",
"company.customers.1": "Nestle-1"
},
{
"name": "Benny",
"department.section": "Technical",
"department.branch.timezone": "UTC",
"company.name": "SAP",
"company.customers.0": "Ford-2",
"company.customers.1": "Nestle-2"
}
]
I had to create a wrapper function called flattenBy that handles mapping the data by a particular key e.g. company and passes it down to your flatten function (along with the current index).
const flatten = (obj, key, index) => {
let keys = {};
for (let i in obj) {
if (!obj.hasOwnProperty(i)) continue;
let ref = i !== key ? obj[i] : obj[i][index];
if (typeof ref == 'object') {
let flatObj = flatten(ref, key);
for (let j in flatObj) {
if (!flatObj.hasOwnProperty(j)) continue;
keys[i + '.' + j] = flatObj[j];
}
} else { keys[i] = obj[i]; }
}
return keys;
}
const flattenBy = (obj, key) =>
obj[key].map((item, index) => flatten(obj, key, index));
const input = {
name: "Benny",
department: { section: "Technical", branch: { timezone: "UTC" } },
company: [
{ name: "SAP", customers: ["Ford-1", "Nestle-1"] },
{ name: "SAP", customers: ["Ford-2", "Nestle-2"] },
]
};
console.log(JSON.stringify(flattenBy(input, 'company'), null, 2));
.as-console-wrapper { top: 0; max-height: 100% !important; }
This code locates all forks (places where arrays are located which indicate multiple possible versions of the input), and constructs a tree of permutations of the input for each fork. Finally, it runs all permutations through a flattener to get the desired dot-delimited result.
Note: h is a value holder, where h.s is set to 1 as soon as the first fork is found. This acts like a kind of global variable across all invocations of getFork on a particular initial object, and forces only one fork to be considered at a time when building up a tree of forks.
const input = {"name":"Benny","department":{"section":"Technical","branch":{"timezone":"UTC"}},"company":[{"name":"SAP","customers":["Ford-1","Nestle-1"]},{"name":"SAP","customers":["Ford-2","Nestle-2"]},{"name":"BAZ","customers":["Maserati","x"],"Somekey":["2","3"]}]}
const flatten = (o, prefix='') => Object.entries(o).flatMap(([k,v])=>v instanceof Object ? flatten(v, `${prefix}${k}.`) : [[`${prefix}${k}`,v]])
const findFork = o => Array.isArray(o) ? o.length : o instanceof Object && Object.values(o).map(findFork).find(i=>i)
const getFork = (o,i,h={s:0}) => o instanceof Object ? (Array.isArray(o) ? h.s ? o : (h.s=1) && o[i] : Object.fromEntries(Object.entries(o).map(([k,v])=>[k, getFork(v, i, h)]))) : o
const recurse = (o,n) => (n = findFork(o)) ? Array(n).fill(0).map((_,i)=>getFork(o, i)).flatMap(recurse) : o
const process = o => recurse(o).map(i=>Object.fromEntries(flatten(i)))
const result = process(input)
console.log(result)

Find all index based on condition

How can I get all the indexes based on a condition for an array of objects?
I have tried the code below, but it's returning only the first occurrence.
a = [
{prop1:"abc",prop2:"yutu"},
{prop1:"bnmb",prop2:"yutu"},
{prop1:"zxvz",prop2:"qwrq"}];
index = a.findIndex(x => x.prop2 ==="yutu");
console.log(index);
findIndex will return only one matching index, You can check value against property prop2 using filter
a = [
{prop1:"abc",prop2:"yutu"},
{prop1:"bnmb",prop2:"yutu"},
{prop1:"zxvz",prop2:"qwrq"}];
const allIndexes = a
.map((e, i) => e.prop2 === 'yutu' ? i : -1)
.filter(index => index !== -1);
console.log(allIndexes);
// This is one liner solution might not work in older IE ('flatMap')
const notSupportedInIE =a.flatMap((e, i) => e.prop2 === 'yutu' ? i : []);
console.log(notSupportedInIE);
Try Array.reduce
a = [
{prop1:"abc",prop2:"yutu"},
{prop1:"bnmb",prop2:"yutu"},
{prop1:"zxvz",prop2:"qwrq"}];
index = a.reduce((acc, {prop2}, index) => prop2 ==="yutu" ? [...acc, index] : acc, []);
console.log(index);
You can use normal for loop and when ever the prop2 matches push the index in the array
const a = [{
prop1: "abc",
prop2: "yutu"
},
{
prop1: "bnmb",
prop2: "yutu"
},
{
prop1: "zxvz",
prop2: "qwrq"
}
];
const indArr = [];
for (let i = 0; i < a.length; i++) {
if (a[i].prop2 === 'yutu') {
indArr.push(i)
}
}
console.log(indArr);
The findIndex method returns the index of the first element in the
array that satisfies the provided testing function. Otherwise, it
returns -1, indicating that no element passed the test. - MDN
You can use reduce here:
const a = [
{ prop1: "abc", prop2: "yutu" },
{ prop1: "bnmb", prop2: "yutu" },
{ prop1: "zxvz", prop2: "qwrq" },
];
const result = a.reduce((acc, curr, i) => {
if (curr.prop2 === "yutu") acc.push(i);
return acc;
}, []);
console.log(result);
You can simply iterate through objects, e.g.
function getIndexes(hystack, nameOfProperty, needle) {
const res = new Array();
for (const [i, item] of hystack.entries()) {
if (item[nameOfProperty] === needle) res.push(i);
}
return res;
}
const items =
[
{prop1:"a", prop2:"aa"},
{prop1:"b", prop2:"bb"},
{prop1:"c", prop2:"aa"},
{prop1:"c", prop2:"bb"},
{prop1:"d", prop2:"cc"}
];
const indexes = getIndexes(items, 'prop2', 'bb');
console.log('Result', indexes);
You can directly use filter without map function
const a = [
{ prop1: "abc", prop2: "yutu" },
{ prop1: "bnmb", prop2: "yutu" },
{ prop1: "zxvz", prop2: "qwrq" },
];
const res = a.filter((item) => {
return item.prop2==="yutu";
});
console.log(res);

How to Pivot Array of Objects with GroupBy and Sum in Javascipt

I have arr array of objects, I need to pivot it with product,calorie and apply (grouping & sum) on remaining parameters.
And then require data in single object.
I tried below code, it works fine but I divided code in 3 parts.
Could I have better code than this or it is ok.
var arr = [{
"product": "Jam",
"calorie": 2000,
"A": 300,
"B": 500,
"type": "Daily"
},
{
"product": "Sugar",
"calorie": 1000,
"A": 100,
"B": 200,
"type": "Daily"
}
]
var a1 = {}
var a2 = {}
//Step-1 Pivot
for (let i = 0; i < arr.length; i++) {
a1[arr[i]['product']] = arr[i]['calorie'];
}
//Step-2 Group and sum
a2 = groupAndSum(arr, ['type'], ['A', 'B'])[0];
//Step-3 merging.
console.log({ ...a1,
...a2
})
//General grouping and summing function that accepts an
//#Array:Array of objects
//#groupKeys: An array of keys to group by,
//#sumKeys - An array of keys to sum.
function groupAndSum(arr, groupKeys, sumKeys) {
return Object.values(
arr.reduce((acc, curr) => {
const group = groupKeys.map(k => curr[k]).join('-');
acc[group] = acc[group] || Object.fromEntries(groupKeys.map(k => [k, curr[k]]).concat(sumKeys.map(k => [k, 0])));
sumKeys.forEach(k => acc[group][k] += curr[k]);
return acc;
}, {})
);
}
Here a single function which takes 3 params:
const func = (arr, pivot_vals, sum_vals) => {
return arr.reduce((a, v) => {
pivot_vals.forEach((pivot) => {
a[v[pivot[0]]] = v[pivot[1]];
});
sum_vals.forEach((key) => {
if (!a[key]) a[key] = 0;
a[key] += v[key];
});
return a;
},{});
};
arr
containing the data
sum_vals
array with all props you want do be summed
pivot_vals
nested array with the props which should be linked
I wans't sure what to do with the type, since it is a string it can`t be summed. Did you want to count the amount of types ?
let arr = [
{
product: "Jam",
calorie: 2000,
A: 300,
B: 500,
type: "Daily",
},
{
product: "Sugar",
calorie: 1000,
A: 100,
B: 200,
type: "Daily",
},
];
let sum_vals = ["A","B"]
let pivot_vals = [["product", "calorie"]];
const func = (arr, pivot_vals, sum_vals) => {
return arr.reduce((a, v) => {
pivot_vals.forEach((pivot) => {
a[v[pivot[0]]] = v[pivot[1]];
});
sum_vals.forEach((key) => {
if (!a[key]) a[key] = 0;
a[key] += v[key];
});
return a;
},{});
};
console.log(func(arr, pivot_vals, sum_vals));

combining duplicate key's values in JavaScript array

I have an Array that contain some keys/values one of the values is an array I want combining the value of array from all recorded that have same key in my Array.
Below is an Simple Example to demonstrate, I am not able to construct its logic so seeking help in building a logic to it.
[{"somekey":"Some Value Pushed"},{"somekey":"Second Value"}]
I want Result Like,
[{"somekey":["Some Value Pushed","Second Value"]}]
The reduce() function of Array Object in JavaScript can merge any array into a single Object.
I wrote a single-line code to solve this problem.
I updated result with the array.
const arr = [{
somekey: "Some Value Pushed",
},
{
somekey2: "Second Value2",
},
{
somekey: "Some Value Pushed",
},
{
somekey2: "Second Value3",
},
{
somekey3: "",
},
{},
];
const ansObj = arr.reduce(
(prv, cur) => {
Object.entries(cur).forEach(([key, v]) => key in prv ? prv[key].push(v) : (prv[key] = [v]));
return prv;
}, {}
)
const ansArray = Object.entries(ansObj).map(([key, value])=>({[key]:value}));
console.log(ansArray);
You can try something like this:
var array = [{
name: "foo1",
value: "val1"
}, {
name: "foo1",
value: ["val2", "val3"]
}, {
name: "foo2",
value: "val4"
}];
var output = [];
array.forEach(function(item) {
var existing = output.filter(function(v, i) {
return v.name === item.name;
});
if (existing.length) {
var existingIndex = output.indexOf(existing[0]);
output[existingIndex].value = output[existingIndex].value.concat(item.value);
} else {
if (typeof item.value === 'string')
item.value = [item.value];
output.push(item);
}
});
Or, another option using Lodash
function mergeNames (arr) {
return _.chain(arr).groupBy('name').mapValues(function (v) {
return _.chain(v).pluck('value').flattenDeep();
}).value();
}
Maybe something like:
const data = [
{"somekey":"Some Value Pushed"},
{"somekey":"Second Value", "otherkey": 1},
{"otherkey": 2}
];
const merge_and_group = (obj1, obj2) =>
Object.entries(obj2).reduce(
(acc, [key, val]) => {
acc[key] ??= [];
acc[key].push(val);
return acc;
},
obj1
);
const res = data.reduce(merge_and_group, {});
console.log(res);
const arr = [{
"somekey": "Some Value Pushed"
}, {
"somekey2": "Second Value2"
}, {
"somekey": "Some Value Pushed"
}, {
"somekey2": "Second Value3"
}]
const newarr = {}
arr.forEach(obj => {
for (const [key, value] of Object.entries(obj)) {
if (newarr[key]) newarr[key].push(value)
else newarr[key] = [value]
}
})
console.log(newarr)
Array.prototype.reduce() is a possible option.
the reduce() method executes a reducer function which is provided as an input on each element of the array and returning a single output value.
const array = [{"somekey":"Some Value Pushed"},{"somekey":"Second Value"}];
const res = array.reduce((acc, el) => {
const [key, value] = Object.entries(el)[0];
(acc[key] || (acc[key] = [])).push(value);
return acc;
}, {});
console.log(res)
Assuming each element of your array is an object with a single key.
const array = [
{ somekey: "Some Value Pushed" },
{ somekey: "Second Value" },
{ foo: "bar" },
{ foo: "baz" },
{ somekey: "Third Value" },
];
const result = [];
array.forEach(el => {
let [key, value] = Object.entries(el)[0];
for (let el of result) if (key in el) {
el[key].push(value);
return;
}
result.push({ [key]: [value] });
});
console.dir(result);
If your array has only "somekey" as keys then you can use map method as following:
const array = [{"somekey":"Some Value Pushed"},{"somekey":"Second Value"}];
const valuesArray = array.map(obj => obj.somekey);
result = [{"somekey":valuesArray}];
console.log(result)
If your array has other keys along with "somekey" and you like to separate values corresponding to only "somekey" then try the following:
const array = [{"somekey":"Some Value Pushed"},{"somekey":"Second Value"}, {"otherkey":"other Value"}];
const filteredArray = array.filter((obj) => {
return "somekey" in obj
}, []);
const valuesArray = filteredArray.map(obj => obj.somekey);
result = [{"somekey":valuesArray}];
console.log(result)

Json Array compare with different length in javascript

Below code which I am using for creating the new array if the id is the same in arr1 and arr2. But doesn't work since arr1 and arr2 are different. array 1 has index and arr2 is without index. screenshot for your reference. Can someone help?
Note: ID in arr1 is the same as EmpId in arr2
for(let i=0; i<arr1.length; i++) {
merged.push({
...arr1[i],
...(arr2.find((itmInner) => itmInner.id === arr1[i].id))}
);
}
console.log(merged);
Array1 looks like this :
[{"Active":1,"Id":1},
{"Active":1,"Id":3},
{"Active":1,"Id":2}]
Array2 looks something like this:
Below is the sample code on how I am framing array 2:
renderElement(activity){
var arr2 = [] ;
for(var i = 0; i < activity.length; i++) {
obj = activity[i];
if(obj.Id == 28){
fetch(geturl)
.then(function (response) {
return response.json();
})
.then(function (data) {
res = data;
arr2.push(res)
})
}
else{
// Do nothing
}
}
return arr2
}
Calling Render method like below:
outputarray = currentComponent.renderElement(activity);
console.log('output', outputarray)
Expected Output:
[{"Active":1,"Id":1,"Param1": true},
{"Active":1,"Id":3}, / Keep it as such if nothing exists in other array
{"Active":1,"Id":2, "Param2": false}]
You can try this approach instead:
Example #1
const arr1 = [
{ "Active":1, "Id":1 },
{ "Active":1, "Id":3 },
{ "Active":1, "Id":2 }
];
const arr2 = [
{
0: [
{
EmpId1: 1, Param1: true
}
]
},
{
1: [
{
EmpId2: 2,Param2: false
}
]
},
{
2: [
{
EmpId3: 2
}
]
},
];
const response = arr1
.reduce((acc, value) => {
const secondaryData = arr2.map((val, index) => {
const { [`EmpId${index + 1}`]: Id, ...others } = val[Object.keys(val)][0];
return { Id, ...others };
});
const match = secondaryData.findIndex(({ Id }) => Id === value.Id);
if (match >= 0) acc.push({...value, ...secondaryData[match]})
else acc.push(value);
return acc;
}, []);
console.log(response);
Example #2
const arr1 = [
{ "Active":1, "Id":1 },
{ "Active":1, "Id":3 },
{ "Active":1, "Id":2 }
];
const arr2 = [
[
{
EmpId1: 1,
Param1: true
}
],
[
{
EmpId2: 2,
Param2: false
}
],
[
{
EmpId3: 2
}
],
]
const response = arr1
.reduce((acc, value) => {
const secondaryData = arr2.map(([val], index) => {
const { [`EmpId${index + 1}`]: Id, ...others } = val;
return { Id, ...others };
});
const match = secondaryData.findIndex(({ Id }) => Id === value.Id);
if (match >= 0) acc.push({...value, ...secondaryData[match]})
else acc.push(value);
return acc;
}, []);
console.log(response);
Basically you can create a hash map by a object property and join on that property all the arrays, i.e. reduce an array of arrays into a result object, then convert the object's values back to an array. Since each array is reduced this means each array is only traversed once O(n) and the map object provides constant time O(1) lookup to match objects. This keeps the solution closer to O(n) rather than other solutions with a nested O(n) findIndex search, which yields a solution closer to O(n^2).
const mergeByField = (...arrays) => {
return Object.values(
arrays.reduce(
(result, { data, field }) => ({
...data.flat().reduce(
(obj, el) => ({
...obj,
[el[field]]: {
...obj[el[field]],
...el
}
}),
result
)
}),
{}
)
);
};
Load each array into a payload object that specifies the field key to match on. This will return all fields used to match by, but these can safely be ignored later, or removed, whatever you need. Example:
mergeByField(
{ data: arr1, field: "Id" },
{ data: arr2, field: "EmpId" },
);
const arr1 = [
{
Active: 1,
Id: 1
},
{
Active: 1,
Id: 2
},
{
Active: 1,
Id: 3
}
];
const arr2 = [[{ EmpId: 1, Param1: true }], [{ EmpId: 3, Param2: false }]];
const mergeByField = (...arrays) => {
return Object.values(
arrays.reduce(
(result, { data, field }) => ({
...data.flat().reduce(
(obj, el) => ({
...obj,
[el[field]]: {
...obj[el[field]],
...el
}
}),
result
)
}),
{}
)
);
};
console.log(
mergeByField({ data: arr1, field: "Id" }, { data: arr2, field: "EmpId" })
);

Categories