How to display nested key of object from left to right? - javascript

I have an object
var tree = {
17:{
1:{
3:{},
4:{}
},
2:{
5:{},
6:{}
}
}
};
How to display the keys in this order 17, 1, 2, 3,4, 5,6 ?
i have tried this function:
var arr = [] ;
var arrObject = [] ;
function printValues(obj) {
for (var key in obj) {
arr.push(key);
if (typeof obj[key] === "object") {
arrObject.push(obj[key]);
printValues(obj[key]);
}
}
}
printValues(tree);
the result is 17,1,3,42,5,6 .
and i need 17, 1, 2, 3,4, 5,6

The following uses a recursive function to extract all the nested keys associated with their depth in the object. It then sorts the results by depth.
Note that the approach may change the order of the keys at a given depth. To demonstrate this, I change the 3 in your example to 99. The returned results include "4", "99", not "99", "4". However, as pointed out in the comment by #deceze, the order of properties in an object is undefined anyway, so changing the order within a given object depth shouldn't (hopefully) be a problem. (If it is a problem then you need a different approach, e.g. using an array instead of an object.)
Note also that the code below returns an array of strings. This would be especially appropriate if some of your keys are explicitly strings, e.g. using letters. If you really want the results to be numerical, just add a + to the map command, i.e. ... .map(elmt => +elmt[1]).
const getKeysOrderedByDepth = obj => {
let arr = [], level = 0;
const getKeys = obj => {
level += 1;
for (let key in obj) {
arr.push([level, key]);
const val = obj[key];
getKeys(obj[key]);
}
level -= 1;
};
getKeys(obj);
return arr.sort((a, b) => a[0] - b[0]).map(elmt => elmt[1]);
};
let tree = {
17: {
1: {
99: {},
4: {}
},
2: {
5: {},
6: {}
}
}
};
console.log(getKeysOrderedByDepth(tree));

This is works for me(changed):
const tree = {
first:{
1:{
3:{
7: 7,
8: 8,
},
4:{
9: 9,
10: 10,
}
},
2:{
5:{
20: {
30: 30,
},
21: {
31: 31,
}
},
6:{
22: 22,
}
},
},
};
const keys = [];
/**
* Handle merged values
* #param values
*/
function handleData(values) {
let subValues = {};
for (let key in values) {
keys.push(key);
Object.assign(subValues, handle(values[key]));
}
// If have values, handle them
if (Object.keys(subValues).length) handleData(subValues);
}
/**
* Handle one value
* #param value
* #returns {{}}
*/
function handle(value) {
if (Object.keys(value).length) {
return Object.assign({}, value);
}
}
// Handle our data
handleData(tree);
console.log(keys); // ['first',1,2,3,4,5,6,7,8,9,10,20,21,22,30,31]

Related

How to recursively check property types in an object

I'm writing a function that takes in an object (A), compares it with another object (B) and creates a new object (C). Both A and B objects are symmetrical (same amount of properties, same keys) but the type of their values can differ. Eg: A.amount can be '11' while B.amount is a number. The end result should be an object C that has the values from A with the types from B.
In the function I came up with, I'm looping through all properties in object A, checking the type of the properties in object B with a switch/case statement, applying type conversion (like .toString()) and adding the corrected property to object C.
I would like the code to be recursive but as soon as there are nested objects involved I do not know how to reach the properties in B nor create the equivalent in C.
Example of an A object:
const data = {
a: "15",
b: "foo",
c: false,
d: {
da: 99,
db: [{
dba: "1.2",
dbb: true
}]
}
}
Example of a B object:
const targetType = {
a: 27,
b: "foofoo",
c: true,
d: {
da: "bar",
db: [{
dba: 4,
dbb: false
}]
}
}
Example of a C object -values from A, types from B:
const finalObject = {
a: 15,
b: "foo",
c: false,
d: {
da: "99",
db: [{
dba: 1.2,
dbb: true
}]
}
}
My function:
//data = object A
//targetType = object B
export function typeConversion(data: any, targetType: any) {
const resultObj = {};
Object.keys(data).forEach((key) => {
switch (typeof targetType[key]) {
case 'string':
resultObj[key] = data[key].toString();
break;
case 'boolean':
resultObj[key] = data[key] ? 'Yes' : 'No';
break;
case 'number':
resultObj[key] = Number(data[key]);
break;
//here is where it gets tricky:
case 'object':
if (Array.isArray(data[key])) {
const dataArray: any = [];
data[key].forEach((o) => {
//all objs in the array have the same shape, hence comparing to [0]
dataArray.push(typeConversion(o, targetType[key][0]));
});
resultObj[key] = dataArray;
} else {
const dataObj = {};
Object.keys(data[key]).forEach((subkey) => {
dataObj[subkey] = typeConversion(subkey, targetType[key][subkey]);
});
resultObj[key] = dataObj;
}
break;
}
});
return resultObj;
}
console.log(typeConversion(data, targetType))
The moment there is a nested object and typeConversion is called recursively, it will fail to find the path to the property in object B. I could add an optional parameter to the function for the 'parent property', but that would only work for one level of depth.
If there is a way to make this recursive, it can't be by coding the path to targetType[like][this].
TypeScript Playground example
All ideas welcome, perhaps I'm approaching the whole thing wrong.
I made some changes in your function to recursively create the final object. Although this is not Typescript specific problem, I wonder what is the use case for this :)
const transform = (data, targetType) => {
let finalObject = {};
const keys = Object.keys(data);
for (const key of keys) {
// If key is Array [], recursively add each element in Array
if (data[key] instanceof Array) {
finalObject[key] = [];
for (let i = 0; i < data[key].length; i++) {
const res = transform(data[key][i], targetType[key][i]);
finalObject[key].push(res);
}
}
// If key is Object {}, recursively add Object keys
else if (data[key] instanceof Object) {
finalObject[key] = transform(data[key], targetType[key]);
}
// If key is Primitive, we can directly add key
else {
switch (typeof targetType[key]) {
case 'string':
finalObject[key] = data[key].toString();
break;
case 'boolean':
finalObject[key] = data[key] ? 'Yes' : 'No';
break;
case 'number':
finalObject[key] = Number(data[key]);
break;
}
}
}
return finalObject;
};
const data = {
a: "15",
b: "foo",
c: false,
d: {
da: 99,
db: [{
dba: "1.2",
dbb: true
}]
}
}
const targetType = {
a: 27,
b: "foofoo",
c: true,
d: {
da: "bar",
db: [{
dba: 4,
dbb: false
}]
}
}
const finalObject = transform(data, targetType);
console.log('Final Object : ', finalObject);

forEach method seems to skip an entry

Aim
I am trying to make a function which would take an array of "votes" and return an object containing the number of times each "candidate" received a score of 1.
For example an array such as:
[
{
"blue": 1,
"red": 3,
"purple": 2,
"yellow": 4
},
{
"blue": 2,
"red": 3,
"purple": 4,
"yellow": 1
},
{
"blue": 1,
"red": 2,
"purple": 4,
"yellow": 3
},
{
"blue": 3,
"red": 4,
"purple": 2,
"yellow": 1
}
];
should return an object
{
"blue": 2,
"red": 0,
"purple": 0,
"yellow": 2
}
Current Code
Currently I have written the function
// adds up the first choice results from raw data
// return object containing number of first choice votes each candidate received
const add_first_choices = function (raw_data) {
// create object to store number of first choices
const storage_obj = empty_candidate_obj(raw_data);
// loop through results, adding first choices to storage_obj
raw_data.forEach(function (single_voter_obj) {
Object.values(single_voter_obj).forEach(function (value) {
if (value === 1) {
storage_obj[getKeyByValue(single_voter_obj, value)] += 1;
}
});
});
return storage_obj;
};
which uses the following two other functions
// returns object of candidate names, each with value of 0
const empty_candidate_obj = function (raw_data) {
const input_data = raw_data;
let first_vote = input_data[0];
const keys = Object.keys(first_vote);
keys.forEach(function (key) {
first_vote[key] = 0;
});
return first_vote;
};
and
// returns key from object value
const getKeyByValue = function (object, value) {
return Object.keys(object).find((key) => object[key] === value);
};
Problem
When inputting the above array into my function it returns
{
blue: 1,
red: 0,
purple: 0,
yellow: 2
}
=> Not as expected!
Do you know what I have done wrong?
Thanks for any replies :)
The issue was with this line:
const input_data = raw_data;
Copying an array of objects is problematic because copying the array doesn't automatically make new copies of the objects. It's just a new array with references to the original objects, so if you change an object in the new array you're changing the original object.
So you need to make new copies of the objects too:
const input_data = raw_data.map(obj => ({...obj}));
You can solve your problem slightly simpler with reduce.
const data = [{"blue":1,"red":3,"purple":2,"yellow":4},{"blue":2,"red":3,"purple":4,"yellow":1},{"blue":1,"red":2,"purple":4,"yellow":3},{"blue":3,"red":4,"purple":2,"yellow":1}];
// We initialise the `reduce` with a new `{}` object,
// which is updated with each iteration.
// `acc` is the accumulator, `c` is the current element
const result = data.reduce((acc, c) => {
// For each object in the array we grab the key and value
Object.entries(c).forEach(([ key, value ]) => {
// If our initial object doesn't already have a key
// that matches, create one and set it to zero
acc[key] = acc[key] || 0;
// And if the value is one, increase the value of that property
if (value === 1) acc[key]++;
});
// Make sure to return the initial object
// for the next iteration
return acc;
}, {});
console.log(result);
With respect to your code the problem is in this line of empty_candidate_obj funcation
let first_vote = input_data[0];
Update you code to send a copy
let first_vote = {...input_data[0]};
Object works on reference. so it's like your first object of your dataset values are updated to 0 as well with your empty object
You probably want to use a reducer something like this:
const results = [
{
"blue": 1,
"red": 3,
"purple": 2,
"yellow": 4
},
{
"blue": 2,
"red": 3,
"purple": 4,
"yellow": 1
},
{
"blue": 1,
"red": 2,
"purple": 4,
"yellow": 3
},
{
"blue": 3,
"red": 4,
"purple": 2,
"yellow": 1
}
];
const empty_obj = {
"blue": 0,
"red": 0,
"purple": 0,
"yellow": 0
}
result = results.reduce( reducer , empty_obj)
console.log( result )
function reducer( acc, val ) {
for( key in val )
if( val[key] === 1 ) acc[key]++;
return acc;
}
Try this function:
function candidateScore1Times(array) {
const newObj = {}
for (const score of array) {
Object.keys(score).forEach(elem => {
if (newObj[elem] != null) {
if (score[elem] == 1) {
newObj[elem]++
}
} else {
score[elem] == 1 ? newObj[elem] = 1 : newObj[elem] = 0
}
})
}
return newObj
}

Another javascript array alphabetical sorting hardtime

I have an array that looks like this, how can I sort it alphabetically without loosing the key?
var items = [
{ 11: 'Edward' },
{ 12: 'Sharpe' },
{ 13: 'Alvin' }
];
You can sort the items array using Object.values.
const items = [
{ 11: 'Edward' },
{ 12: 'Sharpe' },
{ 13: 'Alvin' }
];
items.sort((a, b) => Object.values(a)[0] > Object.values(b)[0]);
console.log(items);
If the objects have only one key, then you can use Object.keys to retrieve that key an then sort:
var items = [
{ '11': 'Edward' },
{ '12': 'Sharpe' },
{ '13': 'Alvin' }
];
items.sort(function(a, b) {
var akey = Object.keys(a) [0], // get a's key
bkey = Object.keys(b) [0]; // get b's key
return a[akey].localeCompare(b[bkey]); // compare the values using those keys
});
console.log(items);
By using Object.keys, since they only have one value we don't know, we can use the length property minus one to get the actual key reference.
var items = [
{ 11: 'Edward' },
{ 12: 'Sharpe' },
{ 13: 'Alvin' }
];
items.sort(function(a, b){
var c = Object.keys(a);
var d = Object.keys(b);
return a[c[c.length-1]] > b[d[d.length-1]] ? 1: -1;
}
)
console.log(items);

How to convert an Object {} to an Array [] of key-value pairs in JavaScript

I want to convert an object like this:
{"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
into an array of key-value pairs like this:
[[1,5],[2,7],[3,0],[4,0]...].
How can I convert an Object to an Array of key-value pairs in JavaScript?
You can use Object.keys() and map() to do this
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map((key) => [Number(key), obj[key]]);
console.log(result);
The best way is to do:
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.entries(obj);
console.log(result);
Calling entries, as shown here, will return [key, value] pairs, as the caller requested.
Alternatively, you could call Object.values(obj), which would return only values.
Object.entries() returns an array whose elements are arrays corresponding to the enumerable property [key, value] pairs found directly upon object. The ordering of the properties is the same as that given by looping over the property values of the object manually.
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Description
The Object.entries function returns almost the exact output you're asking for, except the keys are strings instead of numbers.
const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
console.log(Object.entries(obj));
If you need the keys to be numbers, you could map the result to a new array with a callback function that replaces the key in each pair with a number coerced from it.
const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
const toNumericPairs = input => {
const entries = Object.entries(input);
return entries.map(entry => Object.assign(entry, { 0: +entry[0] }));
}
console.log(toNumericPairs(obj));
I use an arrow function and Object.assign for the map callback in the example above so that I can keep it in one instruction by leveraging the fact that Object.assign returns the object being assigned to, and a single instruction arrow function's return value is the result of the instruction.
This is equivalent to:
entry => {
entry[0] = +entry[0];
return entry;
}
As mentioned by #TravisClarke in the comments, the map function could be shortened to:
entry => [ +entry[0], entry[1] ]
However, that would create a new array for each key-value pair, instead of modifying the existing array in place, hence doubling the amount of key-value pair arrays created. While the original entries array is still accessible, it and its entries will not be garbage collected.
Now, even though using our in-place method still uses two arrays that hold the key-value pairs (the input and the output arrays), the total number of arrays only changes by one. The input and output arrays aren't actually filled with arrays, but rather references to arrays and those references take up a negligible amount of space in memory.
Modifying each key-value pair in-place results in a negligible amount of memory growth, but requires typing a few more characters.
Creating a new array for each key-value pair results in doubling the amount of memory required, but requires typing a few less characters.
You could go one step further and eliminate growth altogether by modifying the entries array in-place instead of mapping it to a new array:
const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
const toNumericPairs = input => {
const entries = Object.entries(obj);
entries.forEach(entry => entry[0] = +entry[0]);
return entries;
}
console.log(toNumericPairs(obj));
To recap some of these answers now on 2018, where ES6 is the standard.
Starting with the object:
let const={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
Just blindly getting the values on an array, do not care of the keys:
const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.values(obj));
//[9,8,7,6,5,4,3,2,1,0,5]
Simple getting the pairs on an array:
const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj));
//[["1",9],["2",8],["3",7],["4",6],["5",5],["6",4],["7",3],["8",2],["9",1],["10",0],["12",5]]
Same as previous, but with numeric keys on each pair:
const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).map(([k,v])=>[+k,v]));
//[[1,9],[2,8],[3,7],[4,6],[5,5],[6,4],[7,3],[8,2],[9,1],[10,0],[12,5]]
Using the object property as key for a new array (could create sparse arrays):
const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).reduce((ini,[k,v])=>(ini[k]=v,ini),[]));
//[undefined,9,8,7,6,5,4,3,2,1,0,undefined,5]
This last method, it could also reorganize the array order depending the value of keys. Sometimes this could be the desired behaviour (sometimes don't). But the advantage now is that the values are indexed on the correct array slot, essential and trivial to do searches on it.
Map instead of Array
Finally (not part of the original question, but for completeness), if you need to easy search using the key or the value, but you don't want sparse arrays, no duplicates and no reordering without the need to convert to numeric keys (even can access very complex keys), then array (or object) is not what you need. I will recommend Map instead:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
let r=new Map(Object.entries(obj));
r.get("4"); //6
r.has(8); //true
In Ecmascript 6,
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
var res = Object.entries(obj);
console.log(res);
var obj = {
"1": 5,
"2": 7,
"3": 0,
"4": 0,
"5": 0,
"6": 0,
"7": 0,
"8": 0,
"9": 0,
"10": 0,
"11": 0,
"12": 0
};
var res = Object.entries(obj);
console.log(res);
Yet another solution if Object.entries won't work for you.
const obj = {
'1': 29,
'2': 42
};
const arr = Array.from(Object.keys(obj), k=>[`${k}`, obj[k]]);
console.log(arr);
Use Object.keys and Array#map methods.
var obj = {
"1": 5,
"2": 7,
"3": 0,
"4": 0,
"5": 0,
"6": 0,
"7": 0,
"8": 0,
"9": 0,
"10": 0,
"11": 0,
"12": 0
};
// get all object property names
var res = Object.keys(obj)
// iterate over them and generate the array
.map(function(k) {
// generate the array element
return [+k, obj[k]];
});
console.log(res);
Use Object.entries to get each element of Object in key & value format, then map through them like this:
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var res = Object.entries(obj).map(([k, v]) => ([Number(k), v]));
console.log(res);
But, if you are certain that the keys will be in progressive order you can use Object.values and Array#map to do something like this:
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
// idx is the index, you can use any logic to increment it (starts from 0)
let result = Object.values(obj).map((e, idx) => ([++idx, e]));
console.log(result);
You can use Object.values([]), you might need this polyfill if you don't already:
const objectToValuesPolyfill = (object) => {
return Object.keys(object).map(key => object[key]);
};
Object.values = Object.values || objectToValuesPolyfill;
https://stackoverflow.com/a/54822153/846348
Then you can just do:
var object = {1: 'hello', 2: 'world'};
var array = Object.values(object);
Just remember that arrays in js can only use numerical keys so if you used something else in the object then those will become `0,1,2...x``
It can be useful to remove duplicates for example if you have a unique key.
var obj = {};
object[uniqueKey] = '...';
With lodash, in addition to the answer provided above, you can also have the key in the output array.
Without the object keys in the output array
for:
const array = _.values(obj);
If obj is the following:
{ “art”: { id: 1, title: “aaaa” }, “fiction”: { id: 22, title: “7777”} }
Then array will be:
[ { id: 1, title: “aaaa” }, { id: 22, title: “7777” } ]
With the object keys in the output array
If you write instead ('genre' is a string that you choose):
const array= _.map(obj, (val, id) => {
return { ...val, genre: key };
});
You will get:
[
{ id: 1, title: “aaaa” , genre: “art”},
{ id: 22, title: “7777”, genre: “fiction” }
]
If you are using lodash, it could be as simple as this:
var arr = _.values(obj);
var obj = { "1": 5, "2": 7, "3": 0, "4": 0, "5": 0, "6": 0, "7": 0, "8": 0, "9": 0, "10": 0, "11": 0, "12": 0 }
let objectKeys = Object.keys(obj);
let answer = objectKeys.map(value => {
return [value + ':' + obj[value]]
});
const persons = {
john: { age: 23, year:2010},
jack: { age: 22, year:2011},
jenny: { age: 21, year:2012}
}
const resultArray = Object.keys(persons).map(index => {
let person = persons[index];
return person;
});
//use this for not indexed object to change array
This is my solution, i have the same issue and its seems like this solution work for me.
yourObj = [].concat(yourObj);
or you can use Object.assign():
const obj = { 0: 1, 1: 2, 2: 3};
const arr = Object.assign([], obj);
console.log(arr)
// arr is [1, 2, 3]
Here is a "new" way with es6 using the spread operator in conjunction with Object.entries.
const data = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
const dataSpread = [...Object.entries(data)];
// data spread value is now:
[
[ '1', 5 ], [ '2', 7 ],
[ '3', 0 ], [ '4', 0 ],
[ '5', 0 ], [ '6', 0 ],
[ '7', 0 ], [ '8', 0 ],
[ '9', 0 ], [ '10', 0 ],
[ '11', 0 ], [ '12', 0 ]
]
you can use 3 methods convert object into array (reference for anyone not only for this question (3rd on is the most suitable,answer for this question)
Object.keys() ,Object.values(),andObject.entries()
examples for 3 methods
use Object.keys()
const text= {
quote: 'hello world',
author: 'unknown'
};
const propertyNames = Object.keys(text);
console.log(propertyNames);
result
[ 'quote', 'author' ]
use Object.values()
const propertyValues = Object.values(text);
console.log(propertyValues);
result
[ 'Hello world', 'unknown' ]
use Object.entires()
const propertyValues = Object.entires(text);
console.log(propertyValues);
result
[ [ 'quote', 'Hello world' ], [ 'author', 'unknown' ] ]
Use for in
var obj = { "10":5, "2":7, "3":0, "4":0, "5":0, "6":0, "7":0,
"8":0, "9":0, "10":0, "11":0, "12":0 };
var objectToArray = function(obj) {
var _arr = [];
for (var key in obj) {
_arr.push([key, obj[key]]);
}
return _arr;
}
console.log(objectToArray(obj));
Recursive convert object to array
function is_object(mixed_var) {
if (mixed_var instanceof Array) {
return false;
} else {
return (mixed_var !== null) && (typeof( mixed_var ) == 'object');
}
}
function objectToArray(obj) {
var array = [], tempObject;
for (var key in obj) {
tempObject = obj[key];
if (is_object(obj[key])) {
tempObject = objectToArray(obj[key]);
}
array[key] = tempObject;
}
return array;
}
We can change Number to String type for Key like below:
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map(function(key) {
return [String(key), obj[key]];
});
console.log(result);
you can use _.castArray(obj).
example:
_.castArray({ 'a': 1 });
// => [{ 'a': 1 }]

how to add parents name in an object (got parent count )

I am trying to make a object in which it property have parent count and parent names. I am able to count the parents ..But I want to add the parent name in my code..
Here is my code
https://jsfiddle.net/ood2ezvz/11/
Code
function getParentCount(nodes) {
var parent = {}, o = {};
nodes.forEach(function (n) {
parent[n.node_from] = parent[n.node_from] || [];
n.children.forEach(function (a) {
parent[a.node_to] = parent[a.node_to] || [];
parent[a.node_to].push(n.node_from);
});
});
Object.keys(parent).forEach(function (k) { o[k] = parent[k].length; });
return o;
}
my output
{11: 0, 12: 1, 13: 1, 14: 1, 15: 2, 16: 1, 17: 1, 18: 1, 19: 1}
Expected out put
{
11:{count:0,parent:[]},
12:{count:1,parent:['11']},
13:{count:1,parent:['12']},
14:{count:1,parent:['13']},
15:{count:2,parent:['13','14']},
16:{count:1,parent:['15']},
17:{count:1,parent:['15']},
18:{count:1,parent:['15']},
19:{count:1,parent:['18']},
}
Try to replace :
Object.keys(parent).forEach(function (k) { o[k] = parent[k].length; });
By :
Object.keys(parent).forEach(function (k) {
o[k] = {};
o[k]['count'] = parent[k].length;
o[k]['parent'] = parent[k];
});
I'd suggest converting your structure to something more usable. Since it seems to be a directed graph, a natural representation will be the list of pairs [from, to]:
graph = []
node.forEach(n =>
n.children.forEach(c =>
graph.push([n.node_from, c.node_to])
)
)
Now you can easily find preceding and following nodes for every given node:
nodes_from = n => graph.filter(v => v[0] === n).map(v => v[1])
console.log(nodes_from(15)) // [ 16, 17, 18 ]
nodes_to = n => graph.filter(v => v[1] === n).map(v => v[0])
console.log(nodes_to(15)) // [ 13, 14 ]

Categories

Resources