Sorting arrays and indexes - javascript

I have a problem with sorting a fixed data table. I tried to use this example:
https://github.com/facebook/fixed-data-table/blob/master/examples/old/SortExample.js
When I first sort by name descending, it sorts successfully and brings to the first two lines to these values:
id:11 name:Mary
id:1 name:Mary
....
After that I sorted by name ascending, and then again I sorted by name descending once again.
It brings first two columns these values:
id:1 name:Mary
id:11 name:Mary
....
Why does it change the indexes of the same name values? (id:11 and id:1)
I need the same sort indexes every time. What is the problem and how can I solve it?
var SortTypes = {
ASC: 'ASC',
DESC: 'DESC',
};
function renderDate(/*object*/ cellData) {
return <span>{cellData.toLocaleString()}</span>;
}
var SortExample = React.createClass({
getInitialState() {
return {
rows: [{"id":"1","name":"Mary"},{"id":"2","name":"Felix"},
{"id":"3","name":"Mary"},{"id":"4","name":"Felix"},
{"id":"5","name":"Mary"},{"id":"6","name":"Felix"},
{"id":"7","name":"Mary"},{"id":"8","name":"Felix"},
{"id":"9","name":"Mary"},{"id":"10","name":"Felix"},
{"id":"11","name":"Mary"},{"id":"12","name":"Felix"},
{"id":"13","name":"Mary"},{"id":"14","name":"Felix"},
{"id":"15","name":"Mary"},{"id":"16","name":"Felix"},
{"id":"17","name":"Mary"},{"id":"18","name":"Felix"} ,
{"id":"19","name":"Mary"},{"id":"20","name":"Felix"}],sortBy: 'id',
sortDir: null,
};
},
_rowGetter(rowIndex) {
return this.state.rows[rowIndex];
},
_sortRowsBy(cellDataKey) {
var sortDir = this.state.sortDir;
var sortBy = cellDataKey;
if (sortBy === this.state.sortBy) {
sortDir = this.state.sortDir === SortTypes.ASC ? SortTypes.DESC : SortTypes.ASC;
} else {
sortDir = SortTypes.DESC;
}
var rows = this.state.rows.slice();
rows.sort((a, b) => {
var sortVal = 0;
if (a[sortBy] > b[sortBy]) {
sortVal = 1;
}
if (a[sortBy] < b[sortBy]) {
sortVal = -1;
}
if (sortDir === SortTypes.DESC) {
sortVal = sortVal * -1;
}
return sortVal;
});
this.setState({
rows,
sortBy,
sortDir,
});
},
_renderHeader(label, cellDataKey) {
return (
<a onClick={this._sortRowsBy.bind(null, cellDataKey)}>{label}</a>
);
},
render() {
var sortDirArrow = '';
if (this.state.sortDir !== null){
sortDirArrow = this.state.sortDir === SortTypes.DESC ? ' ↓' : ' ↑';
}
return (
<Table
rowHeight={50}
rowGetter={this._rowGetter}
rowsCount={this.state.rows.length}
headerHeight={50}
width={1000}
height={500}
{...this.props}>
<Column
headerRenderer={this._renderHeader}
label={'id' + (this.state.sortBy === 'id' ? sortDirArrow : '')}
width={100}
dataKey='id'
/>
<Column
headerRenderer={this._renderHeader}
label={'First Name' + (this.state.sortBy === 'name' ? sortDirArrow : '')}
width={200}
dataKey='name'
/>
</Table>
);
},
});
ReactDOM.render(
<SortExample/>,
document.getElementById('app')
)

For a stable sort, you need some more sort parameter like this solution which sorts first by name and then by id.
var rows = [{ "id": "1", "name": "Mary" }, { "id": "2", "name": "Felix" }, { "id": "3", "name": "Mary" }, { "id": "4", "name": "Felix" }, { "id": "5", "name": "Mary" }, { "id": "6", "name": "Felix" }, { "id": "7", "name": "Mary" }, { "id": "8", "name": "Felix" }, { "id": "9", "name": "Mary" }, { "id": "10", "name": "Felix" }, { "id": "11", "name": "Mary" }, { "id": "12", "name": "Felix" }, { "id": "13", "name": "Mary" }, { "id": "14", "name": "Felix" }, { "id": "15", "name": "Mary" }, { "id": "16", "name": "Felix" }, { "id": "17", "name": "Mary" }, { "id": "18", "name": "Felix" }, { "id": "19", "name": "Mary" }, { "id": "20", "name": "Felix" }];
rows.sort(function (a, b) {
return a.name.localeCompare(b.name) || a.id - b.id;
});
document.write('<pre>' + JSON.stringify(rows, 0, 4) + '</pre>');

Related

How to group by and sum an array of objects javascript?

const array = [
{
"data": {
"qty": "5",
"toy": {
"id": 3,
},
"available": "yes",
}
},
{
"data": {
"qty": "5",
"toy": {
"id": 10,
},
"available": "no"
}
},
{
"data": {
"qty": "59",
"toy": {
"id": 10,
},
"available": "yes",
}
},
{
"data": {
"qty": "5",
"toy": {
"id": 3,
},
"available": "yes",
}
}
]
var result = [];
array.reduce(function(res, value) {
if (!res['data']['toy'] || !res['data']['toy']['data']) {
res['data'] = {...value['data'] };
result.push(res['data'])
}
if (res['data']['available'] === value['data']['available'] && res['data']['toy']['id'] === value['data']['toy']['id']) {
res['data']['qty'] = parseInt(res['data']['qty']) + parseInt(value['data'].qty)
}
return res;
}, {'data': {}});
console.log(result)
I am working on a js project and I need a bit of help here. From the array, How to get a new array that has qty as the sum of the other qty value which data.toy.id and available same. i.e. I want the below array. My code is not working as excepted. Changes to the same or new code are also fine. Thank you.
const array = [
{
"data": {
"qty": "10",
"toy": {
"id": 3,
},
"available": "yes",
}
},
{
"data": {
"qty": "5",
"toy": {
"id": 10,
},
"available": "no"
}
},
{
"data": {
"qty": "59",
"toy": {
"id": 10,
},
"available": "yes",
}
}
]
You group the array into an object, where the keys are concatenation of available and id properties and finally transform the object back to an array using Object.values.
const
array = [
{ data: { qty: "5", toy: { id: 3 }, available: "yes" } },
{ data: { qty: "5", toy: { id: 10 }, available: "no" } },
{ data: { qty: "59", toy: { id: 10 }, available: "yes" } },
{ data: { qty: "5", toy: { id: 3 }, available: "yes" } },
],
result = Object.values(
array.reduce((r, { data }) => {
const k = data.available + data.toy.id;
if (r[k]) {
r[k].data.qty = String(Number(r[k].data.qty) + Number(data.qty));
} else {
r[k] = { data };
}
return r;
}, {})
);
console.log(result);
I'd suggest using Array.reduce() to group by a key, which will be combined value of the toy id and the available property.
We'd create a map of all toys based on this key, summing the quantity for each.
Finally, we'll use Object.values() to convert back into an array.
const array = [ { "data": { "qty": "5", "toy": { "id": 3, }, "available": "yes", } }, { "data": { "qty": "5", "toy": { "id": 10, }, "available": "no" } }, { "data": { "qty": "59", "toy": { "id": 10, }, "available": "yes", } }, { "data": { "qty": "5", "toy": { "id": 3, }, "available": "yes", } } ];
const result = Object.values(array.reduce((acc, { data: { qty, toy, available } }) => {
const key = `${toy.id}-${available}`;
acc[key] = acc[key] || { data: { qty: 0, toy, available } };
acc[key].data.qty += Number(qty);
return acc;
}, {}))
console.log('Result:', result)
.as-console-wrapper { max-height: 100% !important; }
You can use Array#reduce() to create arrayHash object using as keys: ${c.data.toy.id}-${c.data.available}
Code:
const array = [{data: {qty: '5',toy: {id: 3,},available: 'yes',},},{data: {qty: '5',toy: {id: 10,},available: 'no',},},{data: {qty: '59',toy: {id: 10,},available: 'yes',},},{data: {qty: '5',toy: {id: 3,},available: 'yes',},},]
const arrayHash = array.reduce((a, { data }) => {
const key = `${data.toy.id}-${data.available}`
a[key] = a[key] || { data: { ...data, qty: 0 } }
a[key].data.qty = (+a[key].data.qty + +data.qty).toString();
return a
}, {})
const result = Object.values(arrayHash)
console.log(result)
I'd use just reduce
const a1 = [
{
"data": {
"qty": "5",
"toy": {
"id": 3,
},
"available": "yes",
}
},
{
"data": {
"qty": "5",
"toy": {
"id": 10,
},
"available": "no"
}
},
{
"data": {
"qty": "59",
"toy": {
"id": 10,
},
"available": "yes",
}
},
{
"data": {
"qty": "5",
"toy": {
"id": 3,
},
"available": "yes",
}
}
]
const a2 = a1.reduce((acc, it) => {
let found = acc.find(
dp => dp.data.toy.id === it.data.toy.id && dp.data.available === it.data.available
)
if(found){
found.data.qty = ( Number(found.data.qty) + Number(it.data.qty) ).toString()
}
else acc.push(it)
return acc
}, [])
console.log(JSON.stringify(a2, null,2))

Comparing an array with another array plus adding a counter

So I'm reformatting my data and I noticed that my data isn't quite getting restructured the way I want it to. I noticed that my results come back as
[
{
"name": "sites",
"parent": null,
"count": 3
},
{
"name": "group1",
"parent": "sites",
"count": 3
},
{
"name": "bk",
"parent": "group1",
"count": 3
},
{
"name": "sitepages",
"parent": "bk",
"count": 1
},
{
"name": "home.aspx",
"parent": "sitepages",
"count": 1
}
]
It isn't grabbing my "not matches". I've spent so much time looking it over and I'm coming to a blank. It should be
[
{
"name": "sites",
"parent": null,
"count": 3
},
{
"name": "group1",
"parent": "sites",
"count": 3
},
{
"name": "bk",
"parent": "group1",
"count": 3
},
{
"name": "sitepages",
"parent": "bk",
"count": 1
},
{
"name": "home.aspx",
"parent": "sitepages",
"count": 1
},
{
"name": "tester",
"parent": "bk",
"count": 1
},
{
"name": "tester",
"parent": "home.aspx",
"count": 1
},
{
"name": "_layouts",
"parent": "bk",
"count": 1
},
{
"name": "15",
"parent": "_layouts",
"count": 1
},
{
"name": "upload.aspx",
"parent": "15",
"count": 1
},
]
I believe something is missing in my loop.
var testArr = [
{
Author: { Title: "Mitchell" },
BrowserType: "FireFox",
Created: "2017-04-25T16:39:40Z",
pathname: "sites/group1/bk/sitepages/home.aspx"
},
{
Author: { Title: "Pierre" },
BrowserType: "Opera",
Created: "2017-04-25T16:39:40Z",
pathname: "sites/group1/bk/tester/home.aspx"
},
{
Author: { Title: "Mizell" },
BrowserType: "IE",
Created: "2017-04-25T16:47:02Z",
pathname: "sites/group1/bk/_layouts/15/upload.aspx"
}
];
function reduceData(data) {
var root = null;
var newArr = null;
var itemContainer = [];
var masterArr = [];
var filteredArr = [];
data.forEach(function (props, idx) {
//check the last character of the pathname is "/" and removes it
if (props.pathname.charAt(props.pathname.length - 1) === "/") {
props.pathname = props.pathname.substring(0, props.pathname.length - 1);
}
//lowercase the pathname + split into strings
props.pathname = props.pathname.toLowerCase().split("/");
//format the pathname
var lastItem = "";
newArr = props.pathname.reduce(function (acc, props, index) {
if (acc.length === 0) {
acc.push({ name: props, parent: null, count: 1 });
lastItem = props;
} else {
acc.push({ name: props, parent: lastItem, count: 1 });
lastItem = props;
}
return acc;
}, []);
//The first iteration
if (idx === 0) {
itemContainer = newArr;
} else {
for (var i = 0; i < itemContainer.length; i++) {
// Loop for newArr
for (var j = 0; j < newArr.length; j++) {
//compare the element of each and every element from both of the arrays
//console.log(masterArr[i], newArr[j]);
if (
itemContainer[i].name === newArr[j].name &&
itemContainer[i].parent === newArr[j].parent
) {
//Match
masterArr[i] = {
name: itemContainer[i].name,
parent: itemContainer[i].parent,
count: itemContainer[i].count++
};
} else {
//Doesn't Match
masterArr[i] = {
name: itemContainer[i].name,
parent: itemContainer[i].parent,
count: itemContainer[i].count
};
}
}
}
}
});
console.log(masterArr)
}
reduceData(testArr)
ok.. I revamp your code a little..
delete the if else after the //The first iteration, and use this instead..
newArr.forEach((newEl) => {
const matchIdx = masterArr.findIndex((masterEl) => masterEl.name === newEl.name && masterEl.parent === newEl.parent);
if(matchIdx < 0){
masterArr.push(newEl);
}
else {
masterArr[matchIdx].count = masterArr[matchIdx].count + 1;
}
});

Object.assign() for replacing objects of a json

I have JSON looks like this:
{
"ArrayInfo": [
{
"name": "A",
"Id": "1"
},
{
"name": "B",
"Id": "2"
},
{
"name": "C",
"Id": "3"
},
{
"name": "D",
"Id": "4"
}
]
}
I want to replace an object of JSON with another object.For example I have this object :
{"name":"E","Id":"5"}
and it is going to be replaced by this object of JSON:
{"name":"B","Id":"2"}
JSON should look like this :
{
"ArrayInfo": [
{
"name": "A",
"Id": "1"
},
{
"name": "E",
"Id": "5"
},
{
"name": "C",
"Id": "3"
},
{
"name": "D",
"Id": "4"
}
]
}
What I did is to use Object.assign but the new object will be added to array instead of replacing.
(all the data is going to be dynamic but for making more understandable I use static data)
const itemToReplace = { "name": "E", "Id": "5" };
const prevItem = ArrayInfo[2]
ArrayInfo = ArrayInfo.map((el, idx) => {
return Object.assign({}, el, { prevItem: itemToReplace });
});
let NewArryInfo = ArrayInfo
console.log(NewArryInfo)
The result of console.log(NewArryInfo) :
{
"ArrayInfo": [
{
"name": "A",
"Id": "1"
},
{
"name": "B",
"Id": "2"
},
{
"name": "C",
"Id": "3"
},
{
"name": "D",
"Id": "4"
}
{
"name": "E",
"Id": "5"
}
]
}
You can use Array.prototype.splice to replace an item in Array.
const replaceItem = {"name":"E","Id":"5"}
const ArrayInfo = [
{
"name": "A",
"Id": "1"
},
{
"name": "B",
"Id": "2"
},
{
"name": "C",
"Id": "3"
},
{
"name": "D",
"Id": "4"
}
];
ArrayInfo.splice(1, 1, replaceItem); // remove second item and replace
console.log(ArrayInfo);
const object = {
"ArrayInfo": [{
"name": "A",
"Id": "1"
},
{
"name": "B",
"Id": "2"
},
{
"name": "C",
"Id": "3"
},
{
"name": "D",
"Id": "4"
}
]
};
const objectToReplace = {
"name": "B",
"Id": "2"
};
const updatedObject = Object.assign({}, object, {
ArrayInfo: object.ArrayInfo.map((info) => {
if (info.Id === objectToReplace.Id && info.name === objectToReplace.name) {
return {
"name": "E",
"Id": "5"
};
}
return info;
})
});
console.log(updatedObject);
const myArr = [
{
"name": "A",
"Id": "1"
},
{
"name": "B",
"Id": "2"
},
{
"name": "C",
"Id": "3"
},
{
"name": "D",
"Id": "4"
}
];
const replaceObj = (arr, objReplaced, objToReplaceWith) => {
const replacedObjIndex = arr.findIndex(item => JSON.stringify(item) === JSON.stringify(objReplaced));
arr[replacedObjIndex] = objToReplaceWith;
console.log(arr)
return arr;
}
replaceObj(myArr, {"name":"B","Id":"2"}, {"name":"E","Id":"5"});
In this way you can replace any object, from any position in the array.
You won't have to worry about the position of the item that you want to replace in the array and also you won't need to worry about it's keys or values.
When you map over the array you could check if each item is the one you want to replace, and if it is, return the new item instead.
ArrayInfo = ArrayInfo.map((el, idx) => {
if (el.id === prevItem.id && el.name === prevItem.name) {
return itemToReplace;
}
return el;
});
Try this!
let ArrayInfo = [{"name": "A","Id": "1"},{"name": "B","Id": "2"},{"name": "C","Id": "3"},{"name": "D","Id": "4"}];
const onReplace = {"name":"E","Id":"5"};
const toReplace = {"name": "B","Id": "2"};
function replaceArray(array, onReplace, toReplace) {
const removeIndex = array.map(item => { return item.name; }).indexOf(toReplace.name);
array.splice(removeIndex, removeIndex, onReplace);
return array
}
console.log(replaceArray(ArrayInfo, onReplace, toReplace));

Iterate and group the objects using map function

Check for the decimal id and group them accordingly.
Below are the sample and recommended JSON's
Sample JSON
{
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
}
Would like to iterate and Re-structure the above JSON into below recommended format.
Logic: Should check the id(with and without decimals) and group them based on the number.
For Example:
1, 1.1, 1.2.3, 1.4.5 => data1: [{id: 1},{id: 1.1}....]
2, 2.3, 2.3.4 => data2: [{id: 2},{id: 2.3}....]
3, 3.1 => data3: [{id: 3},{id: 3.1}]
Recommended JSON
{
"results": [
{
"data1": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
}
]
},
{
"data2": [
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
}
]
},
{
"data3": [
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
}
]
},
{
"data4": [
{
"name": "Download",
"id": "4.2"
}
]
}
]
}
I have tried the below solution but it doesn't group the object
var formatedJSON = [];
results.map(function(d,i) {
formatedJSON.push({
[data+i]: d
})
});
Thanks in advance.
You can use reduce like this. The idea is to create a key-value pair for each data1, data2 etc so that values in this object are the values you need in the final array. Then use Object.values to get those as an array.
const sampleJson = {"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]}
const grouped = sampleJson.results.reduce((a, v) => {
const key = `data${parseInt(v.id)}`;
(a[key] = a[key] || {[key]: []})[key].push(v);
return a;
},{});
console.log({results: Object.values(grouped)})
One liner / Code-golf:
let s={"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]},k;
console.log({results:Object.values(s.results.reduce((a,v)=>(k=`data${parseInt(v.id)}`,(a[k] = a[k]||{[k]:[]})[k].push(v),a),{}))})
Here you go:
var data = {
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
};
let newSet = new Set();
data.results.forEach(e => {
let key = e.id.substring(0, e.id.indexOf('.'));
console.log(key);
if (newSet.has(key) == false) {
newSet.add(key);
newSet[key] = [];
}
newSet[key].push(e.id);
});
console.log(newSet);
Here's how you'd do it:
var data = {
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
};
var newData = {
"results": {}
};
data.results.forEach(item => {
var num = item.id.slice(0, 1);
if (newData.results["data" + num]) {
newData.results["data" + num].push(item);
} else {
newData.results["data" + num] = [item];
}
})
data = newData;
console.log(data);
What this does is it iterates through each item in results, gets the number at the front of this item's id, and checks if an array of the name data-{num} exists. If the array exists, it's pushed. If it doesn't exist, it's created with the item.
let input = getInput();
let output = input.reduce((acc, curr)=>{
let {id} = curr;
let majorVersion = 'name' + id.split('.')[0];
if(!acc[majorVersion]) acc[majorVersion]= [];
acc[majorVersion].push(curr);
return acc;
},{})
console.log(output)
function getInput(){
return [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
}
One solution with RegEx for finer control as it would differentiate easily between 1 and 11.
Also this will make sure that even if the same version comes in end(say 1.9 in end) it will put it back in data1.
let newArr2 = ({ results }) =>
results.reduce((acc, item) => {
let key = "data" + /^(\d+)\.?.*/.exec(item.id)[1];
let found = acc.find(i => key in i);
found ? found[key].push(item) : acc.push({ [key]: [item] });
return acc;
}, []);

How to create tree view in js

I have a dummy data like this
i need to create a tree like this
CEO
A
A1
A2
My dummy look like this
let d = [
{
"name": "CEO",
"parent": null,
"id": "5847e80312896b2fa49ce428"
},
{
"name": "A",
"parent": "5847e80312896b2fa49ce428",
"id": "5847f58289046550aa05a49d"
},
{
"name": "A1",
"parent": "5847f58289046550aa05a49d",
"id": "584804b073697edd3d372529"
},
{
"name": "A2",
"parent": "5847e80312896b2fa49ce428",
"id": "584804b073697edd3d372539"
}
];
I have tried somthing like this
var newObj = {tree:d.filter(d=>!d.parent)};
var tree = newObj.tree;
for(let k in tree){
for(let i = 0 ; i < tree.length ; i++){
newObj.tree[i]['child']=this.returnChildNode(tree[i].id,d);
}
}
console.log(newObj);
private returnChildNode(parentId ,arr){
if(arr.filter(d=>d.parent===parentId).length < 1) return null ;
else return arr.filter(d=>d.parent===parentId);
}
Output getting is
{
"tree": [
{
"name": "CEO",
"parent": null,
"id": "5847e80312896b2fa49ce428",
"child": [
{
"name": "A",
"parent": "5847e80312896b2fa49ce428",
"id": "5847f58289046550aa05a49d"
},
{
"name": "A2",
"parent": "5847e80312896b2fa49ce428",
"id": "584804b073697edd3d372539"
}
]
}
]
}
How to complete it by recursion for deep going in generic way
Here's a recursive option using reduce
let d = [{
"name": "CEO",
"parent": null,
"id": "5847e80312896b2fa49ce428"
}, {
"name": "A",
"parent": "5847e80312896b2fa49ce428",
"id": "5847f58289046550aa05a49d"
}, {
"name": "A1",
"parent": "5847f58289046550aa05a49d",
"id": "584804b073697edd3d372529"
}, {
"name": "A2",
"parent": "5847e80312896b2fa49ce428",
"id": "584804b073697edd3d372539"
}]
const rec = (parent, arr) => {
const ref = parent ? parent.id : null
const children = arr.reduce((ac, x) => {
if (x.parent === ref)
ac.push(rec(x, arr))
return ac
}, [])
if (parent)
parent.children = children
return (
parent ?
parent :
children[0]
)
}
const res = rec(null, d)
console.log(res)
You can try this :
var data = [
{
name: "CEO",
parent: null,
id: "0"
},
{
name: "A",
parent: "0",
id: "1"
},
{
name: "A1",
parent: "1",
id: "2"
},
{
name: "A2",
parent: "1",
id: "3"
},
{
name: "A3",
parent: "1",
id: "4"
},
{
name: "b",
parent: "0",
id: "5"
},
{
name: "A1",
parent: "5",
id: "6"
},
{
name: "A2",
parent: "5",
id: "7"
},
{
name: "A3",
parent: "5",
id: "8"
},
];
// data is an array in the above format
function toTree(data) {
var childrenById = {}; // of the form id: [child-ids]
var nodes = {}; // of the form id: {name: children: }
var i, row;
// first pass: build child arrays and initial node array
for (i=0; i<data.length; i++) {
row = data[i];
nodes[row.id] = {name: row.name, children: []};
if (row.parent == null) {
// assume -1 is used to mark the root's "parent"
root = row.id;
} else if (childrenById[row.parent] === undefined) {
childrenById[row.parent] = [row.id];
} else {
childrenById[row.parent].push(row.id);
}
}
// second pass: build tree, using the awesome power of recursion!
function expand(id) {
if (childrenById[id] !== undefined) {
for (var i=0; i < childrenById[id].length; i ++) {
var childId = childrenById[id][i];
nodes[id].children.push(expand(childId));
}
}
return nodes[id];
}
return expand(root);
}
console.log(JSON.stringify(toTree(data)));

Categories