Remove object in nested structure by key - javascript

I have an array with objects, that can have children, the children have the same structure as the parent, it's just object nesting basically.
I'm wondering how I can delete one of the objects by key. For example I want to delete the object with id: 1 (which is nested in a children array of another object)
const data = [
{
id: 2,
children: [
{
id: 1,
children: []
}
]
},
{
id: 3,
children: [],
}
]
Moving children up
Would it be possible? If an object with children is deleted, that the children move up to the root?
I've tried
I tried reworking the following function, which returns all id's from my data structure, so it fetches the id, and if there's children, fetches the id's inside those children. But how do I go about deleting an object with that id?
export function flattenFindAttribute (data, attribute) {
return data.map(item => [item[attribute], ...flattenFindAttribute(item.children)]).flat()
}

You just need to use a recursive function call and use Array#splice() method to remove the searched object.
This is how should be your code:
function removeId(data, id) {
data.forEach((o, i) => {
if (o.id && o.id === id) {
data.splice(i, 1);
return true;
} else if (o.children) {
removeId(o.children, id);
}
});
}
Demo:
const data = [{
id: 2,
children: [{
id: 1,
children: []
}]
},
{
id: 3,
children: [],
}
];
function removeId(data, id) {
data.forEach((o, i) => {
if (o.id && o.id === id) {
data.splice(i, 1);
return true;
} else if (o.children) {
removeId(o.children, id);
}
});
}
removeId(data, 1);
console.log(data);
Edit:
If you want to push all the deleted item children into its parent children array, you just need to pass a third param to your function to keep trace of the parent object:
function removeId(data, id, parent) {
data.forEach((o, i) => {
if (o.id && o.id === id) {
if (parent) {
o.children.forEach(c => parent.children.push(c));
}
data.splice(i, 1);
return true;
} else if (o.children) {
removeId(o.children, id, o);
}
});
}
Demo:
var data = [{
id: 2,
children: [{
id: 1,
children: [1, 2]
}]
},
{
id: 3,
children: [],
}
];
function removeId(data, id, parent) {
data.forEach((o, i) => {
if (o.id && o.id === id) {
if (parent) {
o.children.forEach(c=> parent.children.push(c));
}
data.splice(i, 1);
return true;
} else if (o.children) {
removeId(o.children, id, o);
}
});
}
removeId(data, 1);
console.log(data);

You can do this way:
const data = [
{
id: 2,
children: [
{
id: 1,
children: []
}
]
},
{
id: 3,
children: [],
}
]
let deletedObj = {}
function deleteAtId(arr, deleteId) {
const rs = []
arr.forEach(({id, children}) => {
if(id !== deleteId) {
if(!children.length) {
rs.push({id, children})
} else {
const tmp = deleteAtId(children, deleteId)
rs.push({id, children: tmp})
}
} else deletedObj = {id, children}
})
return rs
}
const rs = [...deleteAtId(data, 1), {...deletedObj}]
console.log(rs)

Something like this? It iterates recursively and splices when it finds an object with your id
function removeObject(data, id){
data.forEach(point =>{
if(point.children.length > 0){
removeObject(point.children, id);
}
const index = data.findIndex(x => x.id == id);
if(index > -1){
data.splice(index ,1);
}
});
return data;
}
const data = [
{
id: 2,
children: [
{
id: 1,
children: []
}
]
},
{
id: 3,
children: [],
}
]
removeObject(data, 1);
console.log(data)

Explore the object recursively and delete according to a specified predicate:
const data =[...Array(4)].map(()=> [
{
id: 2,
children: [
{
id: 1,
children: []
}
]
},
{
id: 3,
children: [],
}
]);
function deleteObj(parent, predicate) {
if (predicate(parent)) {
return true;
}
if (typeof parent === 'object') {
if (Array.isArray(parent)) {
for (let i = 0; i < parent.length; i++) {
if (deleteObj(parent[i], predicate)) {
parent.splice(i, 1);
i--;
}
}
} else {
Object.keys(parent).forEach(key => deleteObj(parent[key], predicate) && delete parent[key]);
}
}
return false;
}
console.log('from array:', data[0]);
const test1 = data[1];
const test2 = data[2];
const test3 = data[3];
console.log('delete node with id === 1');
deleteObj(test1, node => node.id === 1);
console.log(test1);
console.log('delete node with id === 3');
deleteObj(test2, node => node.id === 3);
console.log(test2);
console.log('delete node with non empty children');
deleteObj(test3, node => node.children && node.children.length > 0);
console.log(test3);

You can achieve that using Array.reduce with a recursion on the children.
Example:
const data = [
{ id: 1, children: [{ id: 2, children: [] }] },
{
id: 2,
children: [
{
id: 1,
children: [],
},
],
},
{
id: 3,
children: [],
},
{
id: 4,
children: [
{
id: 2,
children: [
{
id: 2,
children: [
{
id: 1,
children: [],
},
{
id: 2,
children: [],
},
],
},
],
},
],
},
];
function removeBy(data, predicate) {
return data.reduce((result, item) => {
if (!predicate(item.id)) {
const newItem = { ...item };
if (item.children.length > 0) {
newItem.children = removeBy(item.children, predicate);
}
result.push(newItem);
}
return result;
}, []);
}
const predicate = value => value === 1;
const result = removeBy(data, predicate);
console.log(result);

This recursive function work for your needings:
function rotateChildren(array, key) {
if (!array || !array.length) {
return array;
}
return array.filter(child => {
if (child) {
child.children = rotateChildren(child.children, key);
return child.id !== key;
}
return !!child;
});
}
const data = [
{
id: 2,
children: [
{
id: 1,
children: []
}
]
},
{
id: 3,
children: [],
}
];
console.log(rotateChildren(data, 1));
console.log(rotateChildren(data, 2));
console.log(rotateChildren(data, 3));

Related

how to return array of objects by checking string exists using javascript

I have array of objects, in which the keys matches,
then return the array of object using javascript
for example,
Passing param zapp is found in arr, return those objects in array using
javascript
var arr =[
{id:1, keys: "zapp"},
{id:2, keys: "zapp, zoin"},
{id:3, keys: "dell"}
];
tried
function checkKeys (arr, keytocheck) {
let result=[]
if(arr.length > 0){
for(let elem of arr) {
const splitkeys = elem.keys(',');
if(elem.keys.indexOf(',') > -1) {
// comma have
if(splitKeys.includes(keytocheck)){
result.push(elem);
}
}
else {
// no comma
if(elem.keys === keytocheck) {
result.push(elem);
}
}
}
}
return result
};
console.log(checkKeys(arr, "zapp"));
Expected Output
[
{id:1, keys: "zapp"},
{id:2, keys: "zapp, zoin"}
]
You are missing split in:
const splitkeys = elem.keys(','); // HERE keys is a string not a function
You have to use split here as:
const splitkeys = elem.keys.split(',');
var arr = [
{ id: 1, keys: 'zapp' },
{ id: 2, keys: 'zapp, zoin' },
{ id: 3, keys: 'dell' },
];
function checkKeys(arr, keytocheck) {
let result = [];
if (arr.length > 0) {
for (let elem of arr) {
const splitkeys = elem.keys.split(',');
if (elem.keys.indexOf(',') > -1) {
// comma have
if (splitkeys.includes(keytocheck)) {
result.push(elem);
}
} else {
// no comma
if (elem.keys === keytocheck) {
result.push(elem);
}
}
}
}
return result;
}
console.log(checkKeys(arr, 'zapp'));
ALTERNATE SOLUTION 1
You can use filter and includes here as:
var arr = [
{ id: 1, keys: 'zapp' },
{ id: 2, keys: 'zapp, zoin' },
{ id: 3, keys: 'dell' },
];
function checkKeys(arr, keytocheck) {
return arr.filter((o) => o.keys.includes(keytocheck));
}
console.log(checkKeys(arr, 'zapp'));
ALTERNATE SOLUTION 2
You can use regex also here as:
var arr = [
{ id: 1, keys: 'zapp' },
{ id: 2, keys: 'zapp, zoin' },
{ id: 3, keys: 'dell' },
];
function checkKeys(arr, keytocheck) {
const regex = new RegExp(keytocheck);
return arr.filter((o) => o.keys.match(regex));
}
console.log(checkKeys(arr, 'zapp'));
You can use filter method
const array = [
{ id: 1, keys: 'zapp' },
{ id: 2, keys: 'zapp, zoin' },
{ id: 3, keys: 'dell' },
];
function filterByKeyValue(arr, key){
return arr.filter((el) => el.keys.toLowerCase().includes(key.toLowerCase()));
}
console.log(filterByKeyValue(array, 'zapp'));

Return similar values ​from multiple array of objects in Javascript

Guys I made a simple example to illustrate my problem. I have 3 object arrays, datasOne, datasTwo and datasThree and what I want is to return a new array only with the objects that are in the 3 arrays. For example, if there is only Gustavo in the 3 arrays, then he will be returned. But there is a detail that if the datasThree is an empty array, then it will bring the data in common only from datasOne and datasTwo and if only the datasTwo which has data and the other two arrays have empty, then it will return data only from datasTwo. In other words it is to return similar data only from arrays that have data. I managed to do this algorithm and it works the way I want, but I would like to know another way to make it less verbose and maybe simpler and also work in case I add more arrays to compare like a dataFour for example. I appreciate anyone who can help me.
My code below:
let datasOne = [
{ id: 1, name: 'Gustavo' },
{ id: 2, name: 'Ana' },
{ id: 3, name: 'Luiz' },
{ id: 8, name: 'Alice' }
]
let datasTwo = [
{ id: 1, name: 'Gustavo' },
{ id: 3, name: 'Luiz' },
{ id: 8, name: 'Alice' }
]
let datasThree = [
{ id: 1, name: 'Gustavo' },
{ id: 3, name: 'Luiz' },
{ id: 2, name: 'Ana' },
{ id: 5, name: 'Kelly' },
{ id: 4, name: 'David' }
]
let filtered
if (datasOne.length > 0 && datasTwo.length > 0 && datasThree.length > 0) {
filtered = datasOne.filter(firstData => {
let f1 = datasThree.filter(
secondData => firstData.id === secondData.id
).length
let f2 = datasTwo.filter(
secondData => firstData.id === secondData.id
).length
if (f1 && f2) {
return true
}
})
} else if (datasOne.length > 0 && datasTwo.length > 0) {
filtered = datasOne.filter(firstData => {
return datasTwo.filter(secondData => firstData.id === secondData.id).length
})
} else if (datasOne.length > 0 && datasThree.length > 0) {
filtered = datasOne.filter(firstData => {
return datasThree.filter(secondData => firstData.id === secondData.id)
.length
})
} else if (datasTwo.length > 0 && datasThree.length > 0) {
filtered = datasTwo.filter(firstData => {
return datasThree.filter(secondData => firstData.id === secondData.id)
.length
})
} else if (datasThree.length > 0) {
filtered = datasThree
} else if (datasTwo.length > 0) {
filtered = datasTwo
} else if (datasOne.length) {
filtered = datasOne
}
console.log(filtered)
1) You can first filter the array which is not empty in arrs.
const arrs = [datasOne, datasTwo, datasThree].filter((a) => a.length);
2) Flatten the arrs array using flat().
arrs.flat()
3) Loop over the flatten array and count the occurrence of all objects using Map
const map = new Map();
for (let o of arrs.flat()) {
map.has(o.id)
? (map.get(o.id).count += 1)
: map.set(o.id, { ...o, count: 1 });
}
4) Loop over the map and collect the result only if it is equal to arrs.length
if (count === arrs.length) result.push(rest);
let datasOne = [
{ id: 1, name: "Gustavo" },
{ id: 2, name: "Ana" },
{ id: 3, name: "Luiz" },
{ id: 8, name: "Alice" },
];
let datasTwo = [
{ id: 1, name: "Gustavo" },
{ id: 3, name: "Luiz" },
{ id: 8, name: "Alice" },
];
let datasThree = [
{ id: 1, name: "Gustavo" },
{ id: 3, name: "Luiz" },
{ id: 2, name: "Ana" },
{ id: 5, name: "Kelly" },
{ id: 4, name: "David" },
];
const arrs = [datasOne, datasTwo, datasThree].filter((a) => a.length);
const map = new Map();
for (let o of arrs.flat()) {
map.has(o.id)
? (map.get(o.id).count += 1)
: map.set(o.id, { ...o, count: 1 });
}
const result = [];
for (let [, obj] of map) {
const { count, ...rest } = obj;
if (count === arrs.length) result.push(rest);
}
console.log(result);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
Not 100% sure it cover all edge cases, but this might get you on the right track:
function filterArrays(...args) {
const arraysWithData = args.filter((array) => array.length > 0);
const [firstArray, ...otherArrays] = arraysWithData;
return firstArray.filter((item) => {
for (const array of otherArrays) {
if (!array.some((itemTwo) => itemTwo.id === item.id)) {
return false;
}
}
return true;
});
}
Usage:
const filtered = filterArrays(datasOne, datasTwo, datasThree);
console.log(filtered)
I believe the code is fairly readable, but if something is not clear I'm glad to clarify.
function merge(arr){
arr = arr.filter(item=>item.length>0)
const map = {};
arr.forEach(item=>{
item.forEach(obj=>{
if(!map[obj.id]){
map[obj.id]=[0,obj];
}
map[obj.id][0]++;
})
})
const len = arr.length;
const ret = [];
Object.keys(map).forEach(item=>{
if(map[item][0]===len){
ret.push(map[item][1])
}
})
return ret;
}
merge([datasOne,datasTwo,datasThree])

Getting occurrences of different values on nested object

I've an array of objects like this:
arrObj = [{
id: 1
data: {
info: {
name: 'jhon'
}
}
},{
id: 1
data: {
info: {
name: 'jane'
}
}
},{
id: 1
data: {
info: {
name: 'jhon'
}
}
}]
And I needs get a summary of occurrences for different values, like this:
{ jane: 1, jhon: 2 }
The big problem is that I need pass the nested prop dynamically:
getSummary('data.info.name',obj) //--> { jane: 1, jhon: 2 }
Any ideas?
You can use the below code, this is just hint. you need to do error handling if some input is not having correct nested keys.
let arrObj = [{
id: 1,
data: {
info: {
name: 'jhon'
}
}
},{
id: 1,
data: {
info: {
name: 'jane'
}
}
},{
id: 1,
data: {
info: {
name: 'jhon'
}
}
}]
const getSummary = (dynamicKeys,obj) => {
const list = dynamicKeys.split('.');
const op = {};
for (let i = 0; i < obj.length; i++) {
let n = 1, key = obj[i][list[0]];
while (list.length > n) {
key = key[list[n]];
n++;
}
op[key] = op[key] ? op[key] + 1 : 1;
}
return op;
}
const test = getSummary('data.info.name', arrObj);
console.log(test)
A possible solution could be as below. Here at first given prop is found out from each element of arrayObj. If the finding isn't successful, the element is skipped and move to next. When the finding is successful, append the finding value to summary if it does not exist in summary or increment the existing value. You can change the code as your requirements.
const arrObj = [{
id: 1,
data: {
info: {
name: 'jhon'
}
}
}, {
id: 1,
data: {
info: {
name: 'jane'
}
}
}, {
id: 1,
data: {
info: {
name: 'jhon'
}
}
}];
const getSummary = (prop, arr) => {
const keys = prop.split('.');
const findPropValue = (elem) =>
keys.reduce((val, key, index) => {
if (index === 0) return elem[key];
return (val && val[key]) || val
}, null);
return arr.reduce((sum, curr) => {
const key = findPropValue(curr);
if (!key) return sum;
sum[key] = (sum[key] && sum[key] + 1) || 1;
return sum;
}, {});
};
console.log(getSummary('data.info.name', arrObj));
Go over elements using forEach. For each object, access the value and build a res object with keys as value (eg jane) and object values are aggregated.
[Access the value, by split the path, access object nested using reduce)
const getSummary = (path, items) => {
const paths = path.split(".");
const res = {};
items.forEach((item) => {
const value = paths.reduce((acc, cur) => acc[cur], item);
res[value] = (res[value] ?? 0) + 1;
});
return res;
};
arrObj = [
{
id: 1,
data: {
info: {
name: "jhon",
},
},
},
{
id: 1,
data: {
info: {
name: "jane",
},
},
},
{
id: 1,
data: {
info: {
name: "jhon",
},
},
},
];
const output = getSummary("data.info.name", arrObj);
console.log(output);

Sort entire nested object by property in JavaScript

I would like to loop through a deeply nested object, and sort each level based on a property. In this case its id
Here's my object (there will me more levels, I just added 3 levels here for readability):
const myObj = [
{
id: 15,
children: [
{
id: 9,
children: [
{
id: 4,
children: []
},
{
id: 1,
children: []
}
]
},
{
id: 4,
children: [
{
id: 35,
children: [
{
id: 12,
children: []
},
{
id: 8,
children: []
}
]
},
{
id: 30,
children: [],
}
]
},
]
},
{
id: 2,
children: [
{
id: 9,
children: []
},
{
id: 3,
children: []
},
]
}
]
Here's the desired output:
const myObj = [
{
id: 2,
children: [
{
id: 3,
children: []
},
{
id: 9,
children: []
}
]
},
{
id: 15,
children: [
{
id: 4,
children: [
{
id: 30,
children: [],
},
{
id: 35,
children: [
{
id: 8,
children: []
},
{
id: 12,
children: []
}
]
},
]
},
{
id: 9,
children: [
{
id: 1,
children: []
},
{
id: 4,
children: []
}
]
},
]
}
]
And here's my attempt at sorting it:
const myObj = [{id:15,children:[{id:9,children:[{id:4,children:[]},{id:1,children:[]}]},{id:4,children:[{id:35,children:[{id:12,children:[]},{id:8,children:[]}]},{id:30,children:[],}]},]},{id:2,children:[{id:9,children:[]},{id:3,children:[]},]}]
function sortByOrderIndex(obj) {
obj.sort((a, b) => (a.orderindex > b.orderindex) ? 1 : ((b.orderindex > a.orderindex) ? -1 : 0));
return obj;
}
function sortNestedObj(obj) {
sortByOrderIndex(obj);
for (let i = 0; i < obj.length; i++) {
const t = obj[i];
if (t.children.length !== 0) {
sortNestedObj(t.children);
} else {
return;
}
}
}
console.log(sortByOrderIndex(myObj))
I've created a function that sorts an object, and then tried to create another object that loops through each object that has children and sort those children using the first function. And if those children have children, then sort those and so forth until a child has no children.
You could recursively sort the array and it's object's children like this:
const myObj = [{id:15,children:[{id:9,children:[{id:4,children:[]},{id:1,children:[]}]},{id:4,children:[{id:35,children:[{id:12,children:[]},{id:8,children:[]}]},{id:30,children:[],}]},]},{id:2,children:[{id:9,children:[]},{id:3,children:[]},]}]
function sortArray(array) {
array.sort((a, b) => a.id - b.id);
array.forEach(a => {
if (a.children && a.children.length > 0)
sortArray(a.children)
})
return array;
}
console.log(sortArray(myObj))
You can make a recursive sorting function:
const myObj = [{id:15,children:[{id:9,children:[{id:4,children:[]},{id:1,children:[]}]},{id:4,children:[{id:35,children:[{id:12,children:[]},{id:8,children:[]}]},{id:30,children:[],}]},]},{id:2,children:[{id:9,children:[]},{id:3,children:[]},]}]
const orderChildren = obj => {
obj.children.sort((a, b) => a.id - b.id);
if (obj.children.some(o => o.children.length)) {
obj.children.forEach(child => orderChildren(child));
}
return obj;
};
const myNewObj = myObj.map(o => orderChildren(o)).sort((a, b) => a.id - b.id);
console.log(myNewObj);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can do:
const myObj = [{id: 15,children: [{id: 9,children: [{id: 4,children: []},{id: 1,children: []}]},{id: 4,children: [{id: 35,children: [{id: 12,children: []},{id: 8,children: []}]},{id: 30,children: [],}]},]},{id: 2,children: [{id: 9,children: []},{id: 3,children: []},]}];
const deepSortById = arr => (arr.forEach(a => a.children && deepSortById(a.children)), arr.sort((a, b) => a.id - b.id));
const result = deepSortById(myObj);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I created generic solution for sorting nested arrays by id. My solution works with any nested array and sorts it according to id property. Or by any other property you specify in the method's seconds parameter.
function sortNestedArrays(obj, sortPropertyName) {
Object.keys(obj).forEach((key) => {
if (Array.isArray(obj[key])) {
obj[key].sort((a, b) => a[sortPropertyName] - b[sortPropertyName]);
}
if (!!obj[key] && (typeof obj[key] === 'object' || Array.isArray(obj[key]))) {
sortNestedArrays(obj[key], sortPropertyName);
}
});
return obj;
}
Usage is following:
obj = sortNestedArrays(obj, 'id');

JavaScript remove duplicate object and access data from removed object and append

var array = [{
id: "decafc0ffeefacedbabef00ddeadbeef",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef"
}, {
id: "4bb6ac319db42fabab84826a1c08e8da",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef;;47421d5c40b2f15d801ac6ca0ff4e6cd;;4bb6ac319db42fabab84826a1c08e8da"
}, {
id: "4bb6ac319db42fabab84826a1c08e8da",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef;;4ace8bd1ec354275a813d6e3725047c0;;4bb6ac319db42fabab84826a1c08e8da"
}, {
id: "47421d5c40b2f15d801ac6ca0ff4e6cd",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef;;47421d5c40b2f15d801ac6ca0ff4e6cd"
}, {
id: "4ace8bd1ec354275a813d6e3725047c0",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef;;4ace8bd1ec354275a813d6e3725047c0"
}];
var keyToBeUnique = 'id';
var newarray = array.filter((val, key) => {
return !array.slice(key + 1)
.some((valNew) => {
if(valNew[keyToBeUnique] === val[keyToBeUnique])
valNew['long_id'] = val['long_id'] +','+ valNew['long_id'];
return valNew[keyToBeUnique] === val[keyToBeUnique];
})
});
console.log(newarray);
Looking for a better way to append the long_Id "valNew['long_id'] = val['long_id'] +','+ valNew['long_id'];" which is written inside "some" function
you can get your result using reduce, it is simplier to what you want to achieve.
var array = [{
id: "decafc0ffeefacedbabef00ddeadbeef",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef"
}, {
id: "4bb6ac319db42fabab84826a1c08e8da",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef;;47421d5c40b2f15d801ac6ca0ff4e6cd;;4bb6ac319db42fabab84826a1c08e8da"
}, {
id: "4bb6ac319db42fabab84826a1c08e8da",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef;;4ace8bd1ec354275a813d6e3725047c0;;4bb6ac319db42fabab84826a1c08e8da"
}, {
id: "47421d5c40b2f15d801ac6ca0ff4e6cd",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef;;47421d5c40b2f15d801ac6ca0ff4e6cd"
}, {
id: "4ace8bd1ec354275a813d6e3725047c0",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef;;4ace8bd1ec354275a813d6e3725047c0"
}];
function reducer(array, keyToBeUnique) {
return array.reduce((accum, cv) => {
const index = accum.findIndex(item => item[keyToBeUnique] === cv[keyToBeUnique])
// if the index is -1 it means you dont have that ID yet, then push it.
if (index === -1) {
accum.push(cv)
} else {
// if it is not -1 you can edit the long_id property and add your strings.
accum[index]['long_id'] = accum[index]['long_id'] + ', ' + cv['long_id'];
}
return accum;
}, []);
}
console.log(reducer(array, 'id'));
you can use .map() to extract the ids and a new Set() to remove the duplicates, then remap the resulting array to put back the elements from the original one :
var array = [{
id: "decafc0ffeefacedbabef00ddeadbeef",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef"
}, {
id: "4bb6ac319db42fabab84826a1c08e8da",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef;;47421d5c40b2f15d801ac6ca0ff4e6cd;;4bb6ac319db42fabab84826a1c08e8da"
}, {
id: "4bb6ac319db42fabab84826a1c08e8da",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef;;4ace8bd1ec354275a813d6e3725047c0;;4bb6ac319db42fabab84826a1c08e8da"
}, {
id: "47421d5c40b2f15d801ac6ca0ff4e6cd",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef;;47421d5c40b2f15d801ac6ca0ff4e6cd"
}, {
id: "4ace8bd1ec354275a813d6e3725047c0",
long_id: "1;;decafc0ffeefacedbabef00ddeadbeef;;4ace8bd1ec354275a813d6e3725047c0"
}];
const filterArray = (array, key) => {
const deduped = [...new Set(array.map(e => e[key]))];
const arr = deduped.map(el => {
const ndx = array.findIndex(e => e[key] === el);
return {
[key]: array[ndx][key],
long_id: array.filter(e => e[key] === el).map(e => e.long_id).join(';;')
}
});
return arr;
}
console.log(filterArray(array, 'id'))
As suggested here use an array, hope it helps :)
var array = [{
id: "decafc0ffeefacedbabef00ddeadbeef",
long_id: ["1;;decafc0ffeefacedbabef00ddeadbeef"]
}, {
id: "4bb6ac319db42fabab84826a1c08e8da",
long_id: ["1;;decafc0ffeefacedbabef00ddeadbeef;;47421d5c40b2f15d801ac6ca0ff4e6cd;;4bb6ac319db42fabab84826a1c08e8da"]
}, {
id: "4bb6ac319db42fabab84826a1c08e8da",
long_id: ["1;;decafc0ffeefacedbabef00ddeadbeef;;4ace8bd1ec354275a813d6e3725047c0;;4bb6ac319db42fabab84826a1c08e8da"]
}, {
id: "47421d5c40b2f15d801ac6ca0ff4e6cd",
long_id: ["1;;decafc0ffeefacedbabef00ddeadbeef;;47421d5c40b2f15d801ac6ca0ff4e6cd"]
}, {
id: "4ace8bd1ec354275a813d6e3725047c0",
long_id: ["1;;decafc0ffeefacedbabef00ddeadbeef;;4ace8bd1ec354275a813d6e3725047c0"]
}];
var output = [];
array.forEach(function(item) {
var existing = output.filter(function(v, i) {
return v.id == item.id;
});
if (existing.length) {
var existingIndex = output.indexOf(existing[0]);
output[existingIndex].long_id = output[existingIndex].long_id.concat(item.long_id);
} else {
if (typeof item.value == 'string')
item.long_id = [item.long_id];
output.push(item);
}
});
console.dir(output);

Categories