字符串数组到树数据结构

时间:2018-08-02 20:43:40

标签: javascript data-structures treeview

从服务器返回的数据包含作为层次结构的字符串数组,如下所示:

[
 "house.bedroom.bed",
 "house.kitchen.spoon",
 "house.kitchen.knife",
 "house.bedroom.sofa",
 "house.bedroom.tv",
 "plants.trees",
 "house.birds.parrot.grey"
 ...]

我如何从中创建树型数据结构,以输出树型数据。

像这样:

root
  house
    bedroom
      bed
      sofa
      tv
    kitchen
      spoon
      knife
    birds
      parrot
        grey
  plants
    trees

最简单的方法是什么?

有什么办法可以扭转它?例如问的,我想退回 house.kitchen.knife

预先感谢

4 个答案:

答案 0 :(得分:2)

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));

此代码将以两种方式在mainMap中返回此结构:

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": {}
            }
        }
    }
}

答案 1 :(得分:1)

您可以使用带有嵌套数组的数组,其中第一个元素是名称。

要查找所需的字符串,它使用递归方法,方法是保留实际元素的路径,以便以后加入所需的字符串。

...是的,为什么是数组而不是时髦的对象?很高兴你问。数组允许维持特定顺序,而不必依赖于有序对象的实际实现。

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; }

答案 2 :(得分:0)

这是一种实现方法,它可能不是最有效的,但可行。如果您不希望叶子为空对象,则可以根据需要对其进行修改。

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

答案 3 :(得分:-2)

下面的代码将为您提供包含关键字的最后一个字符串。让我知道这是否不是您想要的东西。

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>