Converting JS object to different order - javascript

I have JS object like this one:
const networkTree = [
{
id: 10,
hasChildren: true,
children: [
{
id: 9,
hasChildren: true,
children: [
{
id: 7,
hasChildren: true,
children: [
{
id: 5,
hasChildren: false,
children: [],
},
{
id: 4,
hasChildren: false,
children: [],
},
],
},
{
id: 6,
hasChildren: true,
children: [
{
id: 3,
hasChildren: false,
children: [],
},
{
id: 2,
hasChildren: false,
children: [],
},
],
},
],
},
{
id: 8,
hasChildren: true,
children: [
{
id: 1,
hasChildren: false,
children: [],
},
{
id: 11,
hasChildren: false,
children: [],
},
],
},
],
},
];
I have to convert it with a function takes input js object like above to this order:
const myTreeData = [
{
name: 'Top Level',
children: [
{
name: 'Level 2: A',
},
{
name: 'Level 2: B',
},
],
},
];
I am stucked at this point:
const convertTree = (array) => (
treeDatas[];
treeData[];
for(i = 0 ; i < array.length ; i++) {
treeDatas.push(array[i]);
treeData[i].name.push(array[i].id);
}
);
If input networkTree[0].id is 15, myTreeData[0].name should be 15. I want to use id's as names on converted object. I don't need hasChildren boolean value. I will use converted object format with react-ds3-component. If you need more information about converted object format please check https://www.npmjs.com/package/react-d3-tree

If I understand you correctly you want to rename id to name and remove hasChildren? Then you can use this recursive function.
const convertTree = (tree) =>
tree.map((node) => ({
name: node.id,
children: convertTree(node.children)
}))
It's the same as this function, just less verbal.
const convertTree = (tree) => {
return tree.map((node) => {
return {
name: node.id,
children: convertTree(node.children)
}
})
}

Related

filter based in criteria of an array of objects inside an array in Javascript

I have this array :
defaultColumnsWithItems = [
{
column: 'Contrie', items: [
{ id: 1, label: 'USA', selectedItem: true },
{ id: 2, label: 'FRANCE', selectedItem: false },
{ id: 2, label: 'MAROC', selectedItem: false }
]
},
{
column: 'Categorie', items:
[
{ id: 0, label: 'Alimentaion', selectedItem: true },
{ id: 1, label: 'ricolage', selectedItem: false },
{ id: 2, label: 'Literie', selectedItem: true },
{ id: 3, label: 'Menage', selectedItem: false },
]
}
];
I want to filter only the elements with selected item withe value equal to true.
I try this:
const columnsWithSelectedItems = colmunsWithItemsToFilter.filter((columnWithItems) => {
return columnWithItems.items.filter( item => item.selectedItem === true)
})
but it return all elements.
Thank you.
Instead of filter the defaultColumnsWithItems, you should return the whole object with the condition for the items array.
In this scenario, we use the map function to return our object and for items array, we use the filter function to filter selectedItem in each item.
const defaultColumnsWithItems = [
{
column: 'Contrie', items: [
{ id: 1, label: 'USA', selectedItem: true },
{ id: 2, label: 'FRANCE', selectedItem: false },
{ id: 2, label: 'MAROC', selectedItem: false }
]
},
{
column: 'Categorie', items:
[
{ id: 0, label: 'Alimentaion', selectedItem: true },
{ id: 1, label: 'ricolage', selectedItem: false },
{ id: 2, label: 'Literie', selectedItem: true },
{ id: 3, label: 'Menage', selectedItem: false },
]
}
]
const items = defaultColumnsWithItems.map(el => {
return {
column: el.column,
items: el.items.filter(i => i.selectedItem)
}
})
console.log('items: ', items);
Try this
defaultColumnsWithItems.map(function(ComparisonResult) {
ComparisonResult.items = ComparisonResult.items.filter(x => x.selectedItem);
return ComparisonResult;
});

In a javascript nested object, How to get all parents attribute chain by a property like id?(If possible, vanilla javascript)

My object list looks like this:
const a = [
{
id: 1,
name: 'NewYork',
children: [],
},
{
id: 2,
name: 'Tokyo',
children: [
{
id: 7,
name: 'Toshima',
children: [],
},
{
id: 8,
name: 'Minato',
children: [
{
id: 17,
name: 'Sugamo',
children: [],
},
{
id: 18,
name: 'Kamiichi',
children: [],
},
],
},
],
},
];
And now I have an id 18, I'd like to make a String like Tokyo>Minato>Kamiichi
How can I make it work in javascript (no third party library) ?
Actually I have a very long nested object.
One way is to use a recursive function for this:
const a = {
companies: [{
id: 1,
name: 'NewYork',
children: [],
},
{
id: 2,
name: 'Tokyo',
children: [{
id: 7,
name: 'Toshima',
children: [],
},
{
id: 8,
name: 'Minato',
children: [{
id: 17,
name: 'Sugamo',
children: [],
},
{
id: 18,
name: 'Kamiichi',
children: [],
},
],
},
],
},
],
};
function getPath(obj, id) {
if (obj.id === id) return obj.name;
for (const child of obj.children) {
const path = getPath(child, id);
if (path) {
return obj.name ? obj.name + '>' + path : path;
}
}
return null;
}
console.log(getPath({
children: a.companies
}, 18));

Filter array in array and get only the filtered items

I have the following array named filters and try to filter it by selected items.
At the end I want to have all filters where a selected item is, but only with the selected items
let filters = [
{
id: 0,
name: 'property',
items: [
{
id: 0,
name: 'x',
isSelected: false
},
{
id: 1,
name: 'y',
isSelected: true
}
]
},
{
id: 1,
name: 'property2',
items: [
{
id: 0,
name: 'x',
isSelected: true
},
{
id: 1,
name: 'y',
isSelected: false
}
]
}
]
I want to get the following array at the end:
let filteredFilters = [
{
id: 0,
name: 'property',
items: [
{
id: 1,
name: 'y',
isSelected: true
}
]
},
{
id: 1,
name: 'property2',
items: [
{
id: 0,
name: 'x',
isSelected: true
}
]
}
]
I tried the following code, but it does not work.
let filteredFilters = filters.filter(filter => {
return filter.items.filter(item => {
return item.isSelected === true;
})
})
You need map + filter since you're dealing with a nested array:
let filters = [
{
id: 0,
name: 'property',
items: [
{
id: 0,
name: 'x',
isSelected: false
},
{
id: 1,
name: 'y',
isSelected: true
}
]
},
{
id: 1,
name: 'property2',
items: [
{
id: 0,
name: 'x',
isSelected: true
},
{
id: 1,
name: 'y',
isSelected: false
}
]
}
]
let filteredFilters =
filters.map(
({items, ...rest}) => ({...rest, items: items.filter(item => item.isSelected)})
)
.filter(x => x.items.length > 0);
console.log(filteredFilters);

flatten tree with javascript and es6 features

i am new in es6 and want to flatten my tree object.
(I'm using reflux - not redux - but flatten state is also a good idea in reflux)
api response:
export const node = {
item: 1,
children: [
{
item: 2,
children: [
{
item: 3,
children: [
{
item: 4,
children: []
},
{
item: 5,
children: []
},
{
item: 6,
children: [
{
item: 7,
children: []
},
{
item: 8,
children: []
},
{
item: 9,
children: []
}
]
}
]
},
{
item: 10,
children: [
{
item: 11,
children: []
},
{
item: 12,
children: [
{
item: 13,
children: []
},
{
item: 14,
children: []
}
]
}
]
}
]
}
]
}
My goal is:
tree= {
byId: {
item1 : {
id: 'item1',
name: 'item1', parent: null,
children : ['item2']
}
}
parent is one id, childrend are array of ids
for building a breadcrumb (using parent) or listing child objects...
get object from id with
tree.byId[someId]
my last try ist to use a recursiv function with es6 spread operator:
const flattenTree = (tree, flattenTree) => {
if (node.children.length) {
node.children.map(child => {
return flattenTree(child, [...tree= { id: child.item}])
})
} else {
return [...tree, tree.byId[cat.item] = { id: cat.item, name: cat.item }]
}
}
sorry I'm first time here, so my post in not well formatted...
thx for help
const tree = {
item: 1,
children: [
{
item: 2,
children: [
{
item: 3,
children: [
{
item: 4,
children: []
},
{
item: 5,
children: []
},
{
item: 6,
children: [
{
item: 7,
children: []
},
{
item: 8,
children: []
},
{
item: 9,
children: []
}
]
}
]
},
{
item: 10,
children: [
{
item: 11,
children: []
},
{
item: 12,
children: [
{
item: 13,
children: []
},
{
item: 14,
children: []
}
]
}
]
}
]
}
]
}
const flattenTree = (tree) => {
const newTree = { byId: {} };
const traverseNode = (node, parent) => {
const id = `item${node.item}`;
newTree.byId[id] = {
id,
name: id,
parent,
children: node.children.map((c) => {
traverseNode(c, id)
return `item${c.item.id}`;
})
}
}
traverseNode(tree, null);
return newTree;
}
The result of flattenTree(tree) will look something like this:
{ byId:
{ item4:
{ id: 'item4', name: 'item4', parent: 'item3', children: [] },
item5:
{ id: 'item5', name: 'item5', parent: 'item3', children: [] },
item7:
{ id: 'item7', name: 'item7', parent: 'item6', children: [] },
item8:
{ id: 'item8', name: 'item8', parent: 'item6', children: [] },
item9:
{ id: 'item9', name: 'item9', parent: 'item6', children: [] },
item6:
{ id: 'item6', name: 'item6', parent: 'item3', children: [Array] },
item3:
{ id: 'item3', name: 'item3', parent: 'item2', children: [Array] },
item11:
{ id: 'item11', name: 'item11', parent: 'item10', children: [] },
item13:
{ id: 'item13', name: 'item13', parent: 'item12', children: [] },
item14:
{ id: 'item14', name: 'item14', parent: 'item12', children: [] },
item12:
{ id: 'item12',
name: 'item12',
parent: 'item10',
children: [Array] },
item10:
{ id: 'item10',
name: 'item10',
parent: 'item2',
children: [Array] },
item2:
{ id: 'item2', name: 'item2', parent: 'item1', children: [Array] },
item1:
{ id: 'item1', name: 'item1', parent: null, children: [Array] } } }
You can use this recursive function:
Main() {
let flattedTree = [];
// We must treat the tree like a node, so we put it inside an array.
let tree = [
{
item: 1,
children: [
{
item: 2,
children: [
{
item: 3,
children: [
{
item: 4,
children: [],
},
{
item: 5,
children: [],
},
{
item: 6,
children: [
{
item: 7,
children: [],
},
{
item: 8,
children: [],
},
{
item: 9,
children: [],
},
],
},
],
},
{
item: 10,
children: [
{
item: 11,
children: [],
},
{
item: 12,
children: [
{
item: 13,
children: [],
},
{
item: 14,
children: [],
},
],
},
],
},
],
},
],
},
];
// After recursive method executed you will have a flattend array.
// flattedTree variable hold the flatted tree.
this.flatten(tree, flattedTree);
}
flatten(nodes: any[], flattedNodes: any[]) {
for (let index = 0; index < nodes.length; index++) {
flattedNodes.push(nodes[index]);
if (nodes[index].children !== undefined)
if (nodes[index].children.length > 0)
this.flatten(nodes[index].children, flattedNodes);
}
}
This is the result:
[{"item":1,"children":[{"item":2,"children":[{"item":3,"children":[{"item":4,"children":[]},{"item":5,"children":[]},{"item":6,"children":[{"item":7,"children":[]},{"item":8,"children":[]},{"item":9,"children":[]}]}]},{"item":10,"children":[{"item":11,"children":[]},{"item":12,"children":[{"item":13,"children":[]},{"item":14,"children":[]}]}]}]}]},{"item":2,"children":[{"item":3,"children":[{"item":4,"children":[]},{"item":5,"children":[]},{"item":6,"children":[{"item":7,"children":[]},{"item":8,"children":[]},{"item":9,"children":[]}]}]},{"item":10,"children":[{"item":11,"children":[]},{"item":12,"children":[{"item":13,"children":[]},{"item":14,"children":[]}]}]}]},{"item":3,"children":[{"item":4,"children":[]},{"item":5,"children":[]},{"item":6,"children":[{"item":7,"children":[]},{"item":8,"children":[]},{"item":9,"children":[]}]}]},{"item":4,"children":[]},{"item":5,"children":[]},{"item":6,"children":[{"item":7,"children":[]},{"item":8,"children":[]},{"item":9,"children":[]}]},{"item":7,"children":[]},{"item":8,"children":[]},{"item":9,"children":[]},{"item":10,"children":[{"item":11,"children":[]},{"item":12,"children":[{"item":13,"children":[]},{"item":14,"children":[]}]}]},{"item":11,"children":[]},{"item":12,"children":[{"item":13,"children":[]},{"item":14,"children":[]}]},{"item":13,"children":[]},{"item":14,"children":[]}]

how to filter nested array like this?

I am having response like below
let m = [
{
name: 'Summary',
subListExpanded: false,
subList: [
]
},
{
name: 'Upload',
subListExpanded: false,
subList: [
]
},
{
name: 'Tasks',
subListExpanded: false,
subList: [
]
},
{
name: 'Dashboard',
subListExpanded: false,
subList: [
]
},
{
name: 'Master',
subListExpanded: false,
subList: [
{
id: 'user-master',
name: 'User-Master'
},
{
id: 'menu-master',
name: 'Menu-Master'
},
{
id: 'entity-master',
name: 'Entity-Master'
},
{
id: 'vendor-master',
name: 'Vendor-Master'
},
{
id: 'xxx-master',
name: 'xxx-Master'
}
]
}
];
If i search m the filter should be like this
[
{
name: 'Summary',
subListExpanded: false,
subList: [
]
},
{
name: 'Master',
subListExpanded: false,
subList: [
{
id: 'user-master',
name: 'User-Master'
},
{
id: 'menu-master',
name: 'Menu-Master'
},
{
id: 'entity-master',
name: 'Entity-Master'
},
{
id: 'vendor-master',
name: 'Vendor-Master'
},
{
id: 'xxx-master',
name: 'xxx-Master'
}
]
}
];
if i search master the filter response should like this?
[
{
name: 'Master',
subListExpanded: false,
subList: [
{
id: 'user-master',
name: 'User-Master'
},
{
id: 'menu-master',
name: 'Menu-Master'
},
{
id: 'entity-master',
name: 'Entity-Master'
},
{
id: 'vendor-master',
name: 'Vendor-Master'
},
{
id: 'xxx-master',
name: 'xxx-Master'
}
]
}
];
if i search xxx-master the filter response should be
[
{
name: 'Master',
subListExpanded: false,
subList: [
{
id: 'xxx-master',
name: 'xxx-Master'
}
]
}
];
if i search slkvcsmcskc filter response like
[]
my typescript code is not working properly .please help me to fix this>
m.filter(x=> x.name.toLowerCase() === search.toLowerCase() || x.subList.some(x1=> x1.name.toLowerCase()===search.toLowerCase()))
The following code gives the desired output. Note that I added some complexity which may not be needed for your use case. However, the example should work for lists with arbitrary deep nesting (see 'bar' example).
let m = [
{
name: 'Summary',
subListExpanded: false,
subList: [
]
},
{
name: 'Upload',
subListExpanded: false,
subList: [
{
name: 'foo',
subList: [
{
name: 'bar',
}
],
}
]
},
{
name: 'Tasks',
subListExpanded: false,
subList: [
]
},
{
name: 'Dashboard',
subListExpanded: false,
subList: [
]
},
{
name: 'Master',
subListExpanded: false,
subList: [
{
id: 'user-master',
name: 'User-Master'
},
{
id: 'menu-master',
name: 'Menu-Master'
},
{
id: 'entity-master',
name: 'Entity-Master'
},
{
id: 'vendor-master',
name: 'Vendor-Master'
},
{
id: 'xxx-master',
name: 'xxx-Master'
}
]
}
];
function search (input, query) {
const queryReg = new RegExp(query, 'i');
function searchInternal (data) {
let result = [];
data.forEach(item => {
const parentMatch = queryReg.test(item.name);
let subMatch = false;
if (item.subList) {
let subResult = searchInternal(item.subList);
subMatch = subResult.length > 0;
item.subList = subMatch ? subResult : [];
}
// push parent if it matches for itself or a child (list) matches
if (parentMatch || subMatch) result.push(item);
});
return result;
}
return searchInternal(JSON.parse(JSON.stringify(input)) /* create a working copy with JSON.parse(...) */);
}
console.log('master', search(m, 'master'));
console.log('xxx-master', search(m, 'xxx-master'));
console.log('m', search(m, 'm'));
console.log('bar', search(m, 'bar'));
console.log('slkvcsmcskc', search(m, 'slkvcsmcskc'));
Actually it should go like this:
obj = {
_id: "sjkd9skj",
data: {
dektop: [
{
x: 2,
y: 3,
t: { key: 'aabbcc'}
},
...
],
mobile: [
{
x: 4,
y: 3,
t: { key: 'ffff'}
},
...
],
print: [
{
x: 7,
y: 5,
t: { key: 'ppp'}
},
...
]
}
}

Categories