Reputation: 95
There is data returned from server containing an array of strings as hierarchy like this:
[
"house.bedroom.bed",
"house.kitchen.spoon",
"house.kitchen.knife",
"house.bedroom.sofa",
"house.bedroom.tv",
"plants.trees",
"house.birds.parrot.grey"
...]
how do i create a tree data structure out of it to make Output the data in tree form.
like this:
root
house
bedroom
bed
sofa
tv
kitchen
spoon
knife
birds
parrot
grey
plants
trees
what is the most simple way to do so ?
and is there any way to reverse it ? for example of asked knife i want to return house.kitchen.knife
thanks in advance
Upvotes: 6
Views: 3312
Reputation: 386868
You could take an array with nested arrays where the first element is the name.
For finding a wanted string, it uses a recursive approach by keeping the path to the actual elements for later joining a wanted string.
... right, why an array and not a funky object? Glad that you asked. Arrays allows to maintain a specific order without relying on actual implementation of ordered objects.
function find([key, values], string, temp = []) {
var result;
temp = temp.concat(key);
if (key === string) {
return temp.slice(1).join('.');
}
values.some(a => result = find(a, string, temp));
return result;
}
var array = ["house.bedroom.bed", "house.kitchen.spoon", "house.kitchen.knife", "house.bedroom.sofa", "house.bedroom.tv", "plants.trees", "house.birds.parrot.grey"],
result = array.reduce((r, s) => {
('root.' + s).split('.').reduce((a, item) => {
var array = a.find(([v]) => v === item);
if (!array) {
a.push(array = [item, []]);
}
return array[1];
}, r);
return r;
}, []).pop();
console.log(find(result, 'knife')); // house.kitchen.knife
console.log(find(result, '42')); // undefined, what else?
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 5
Reputation: 3688
const data = [
"house.bedroom.bed",
"house.kitchen.spoon",
"house.kitchen.knife",
"house.bedroom.sofa",
"house.bedroom.tv",
"plants.trees",
"house.birds.parrot.grey"
];
const mainMapFromStart = {};
const mainMapFromEnd = {};
function set(parts, mainMap) {
let map = mainMap;
for(const item of parts) {
map[item] = map[item] || {};
map = map[item];
}
}
data.map(item => item.split('.')).forEach(parts => {
set(parts, mainMapFromStart);
set(parts.reverse(), mainMapFromEnd);
});
console.log(JSON.stringify(mainMapFromStart, null, 4));
console.log(JSON.stringify(mainMapFromEnd, null, 4));
This code will return this structure in mainMap in both ways:
output:
{
"house": {
"bedroom": {
"bed": {},
"sofa": {},
"tv": {}
},
"kitchen": {
"spoon": {},
"knife": {}
},
"birds": {
"parrot": {
"grey": {}
}
}
},
"plants": {
"trees": {}
}
}
{
"bed": {
"bedroom": {
"house": {}
}
},
"spoon": {
"kitchen": {
"house": {}
}
},
"knife": {
"kitchen": {
"house": {}
}
},
"sofa": {
"bedroom": {
"house": {}
}
},
"tv": {
"bedroom": {
"house": {}
}
},
"trees": {
"plants": {}
},
"grey": {
"parrot": {
"birds": {
"house": {}
}
}
}
}
Upvotes: 4
Reputation: 635
Code below will give you the last string that includes the keyword. Let me know if this wasn't what you were looking for.
let stringsArray = [
"house.bedroom.bed",
"house.kitchen.spoon",
"house.kitchen.knife",
"house.bedroom.sofa",
"house.bedroom.tv",
"plants.trees",
"house.birds.parrot.grey"
];
function findInArray() {
let keyword = document.getElementById('search').value;
let results = document.getElementById('results');
stringsArray.forEach(function(string, index) {
if (string.includes(keyword)) {
results.innerHTML = string;
}
});
}
<label for="search">Search for:</label>
<input type="text" id="search">
<button type="button" onclick='findInArray()'>Search</button>
<span id="results"></span>
Upvotes: -2
Reputation: 16726
here's one way to do it, might not be the most efficient, but works. If you don't want the leafs as empty objects, you can modify it as needed.
var r=[
"house.bedroom.bed",
"house.kitchen.spoon",
"house.kitchen.knife",
"house.bedroom.sofa",
"house.bedroom.tv",
"plants.trees",
"house.birds.parrot.grey"];
var o={}; // output object
function build(o,p){
p.split(".").forEach(function(d){
o = o[d] || (o[d]={});
});
}
r.forEach(function(a,i){ // build up each branch based on path
build(o, a);
});
o
Upvotes: 3