Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 根据特定规则获取自定义数组列表的层次顺序_Javascript_Jquery_Arrays_Algorithm - Fatal编程技术网

Javascript 根据特定规则获取自定义数组列表的层次顺序

Javascript 根据特定规则获取自定义数组列表的层次顺序,javascript,jquery,arrays,algorithm,Javascript,Jquery,Arrays,Algorithm,我想从下面的数组列表中获得层次顺序 var data = [ ['','dog'], ['dog','cat'], ['dog','fish'], ['dog','ark'], ['dog','folder'], ['cat','blue'], ['cat','pencil'], ['cat','mouse'], ['fish','stencil'], ['fish','bread'], ['fish','milk'], [

我想从下面的数组列表中获得层次顺序

var data = [
   ['','dog'],
   ['dog','cat'],
   ['dog','fish'],
   ['dog','ark'],
   ['dog','folder'],
   ['cat','blue'],
   ['cat','pencil'],
   ['cat','mouse'],
   ['fish','stencil'],
   ['fish','bread'],
   ['fish','milk'],
   ['fish','love'],
   ['mouse','tv'],
   ['mouse','oil'],
   ['mouse','car'],
   ['milk','dough'],
   ['milk','butter'],
   ['car','truck']
];
“计算”的方法是从第一个数组开始

['','dog']
注意:我将0索引(“”)称为“父级”,1索引(“”)称为“子级”

因此,我们希望找到以“dog”为父对象的数组,然后检查这些数组,看看它们的子对象是否有父对象,如果没有,则继续下一个数组。(真希望这有道理)

下面是我的上述数据集的订单结果

var result = ['dog', 'cat', 'blue', 'pencil', 'mouse', 'tv', 'oil', 'car', 'truck', 'fish', 'stencil', 'bread', 'milk', 'dough', 'butter', 'love', 'ark', 'folder'];
我尝试了一些非常糟糕的while循环和.filters()来获取包含子索引作为父索引的数组,但失败了


如果有人能对此提供一些见解或返回最终结果的方法,我将不胜感激,因为我无法继续手动计算。

我想,这里是您的算法

  • 将源数组转换为嵌套对象,该对象使用“按引用传递”有效地关联父对象和子对象
  • 下面是一个ES6实现:

    function pairsToIndex(pairs) {
        return pairs.reduce((index, pair, i, list) => {
            let [ parent , child ] = pair;
    
            let parent_exists = index.hasOwnProperty(parent);
            let child_exists = index.hasOwnProperty(child);
    
            if(!parent_exists) {
                index[parent] = { key: parent , children: [] };
            }
    
            if(!child_exists) {
                index[child] =  { key: child  , children: [] };
            }
    
            // now, ensure that parent-child relationship is captured
            let rel_captured = Boolean( index[parent].children.find((c) => c.key === child) );
    
            if(!rel_captured) {
                index[parent].children.push( index[child] );
            }
    
            return index;
        }, {});
    }
    
    let data = [
        ['','dog'],
        ['dog','cat'],
        ['dog','fish'],
        ['dog','ark'],
        ['dog','folder'],
        ['cat','blue'],
        ['cat','pencil'],
        ['cat','mouse'],
        ['fish','stencil'],
        ['fish','bread'],
        ['fish','milk'],
        ['fish','love'],
        ['mouse','tv'],
        ['mouse','oil'],
        ['mouse','car'],
        ['milk','dough'],
        ['milk','butter'],
        ['car','truck']
    ];
    
    let x = pairsToIndex(data);
    console.log(x);
    
    在浏览器的开发控制台中运行该代码。在挖掘对象
    x
    时,您会注意到每个“子对象”的行为就像指向
    x
    的另一个顶级属性的符号链接。实际上,每个“子”都是指向该对象内其他地方的入口。通过引用传递的使用为我们设置了步骤2


  • 通过以深度优先模式递归遍历该对象并返回每个节点的
    属性来序列化该对象
  • 下面是一个简短的例子:

    function listNode(node) {
        return Array.prototype.concat.apply( [node.key] , node.children.map(listNode) );
    }
    
    let out = listNode(x['']); // choosing the entry point to the hierarchy
    console.log(out);
    
    注意,我不得不使用
    apply
    来避免创建一堆嵌套的单元素数组(即使它们的顺序正确)。这可以用
    \uuu0.flatte
    之类的东西来解决,但在这种情况下,对该语言了解多一点就不需要整个库了

    还要注意,
    listNode
    在技术上是在层次结构的子树上操作的。我告诉它从“根”节点开始,您建议它在原始数据集中由空字符串标识。但是,您可以要求它通过传递不同的起点来序列化树的子集,例如
    listNode(x['cat'])
    listNode(x['fish'])

    最后,该算法是无限递归的。如果向脚本提供非常大的数据集,浏览器将停止该脚本。其他JS环境(比如nodejs或react native)不会这样做



    此时,
    out
    是一个数组,它按照您希望的顺序列出原始
    数据中的每个值。

    我想这里是您的算法

  • 将源数组转换为嵌套对象,该对象使用“按引用传递”有效地关联父对象和子对象
  • 下面是一个ES6实现:

    function pairsToIndex(pairs) {
        return pairs.reduce((index, pair, i, list) => {
            let [ parent , child ] = pair;
    
            let parent_exists = index.hasOwnProperty(parent);
            let child_exists = index.hasOwnProperty(child);
    
            if(!parent_exists) {
                index[parent] = { key: parent , children: [] };
            }
    
            if(!child_exists) {
                index[child] =  { key: child  , children: [] };
            }
    
            // now, ensure that parent-child relationship is captured
            let rel_captured = Boolean( index[parent].children.find((c) => c.key === child) );
    
            if(!rel_captured) {
                index[parent].children.push( index[child] );
            }
    
            return index;
        }, {});
    }
    
    let data = [
        ['','dog'],
        ['dog','cat'],
        ['dog','fish'],
        ['dog','ark'],
        ['dog','folder'],
        ['cat','blue'],
        ['cat','pencil'],
        ['cat','mouse'],
        ['fish','stencil'],
        ['fish','bread'],
        ['fish','milk'],
        ['fish','love'],
        ['mouse','tv'],
        ['mouse','oil'],
        ['mouse','car'],
        ['milk','dough'],
        ['milk','butter'],
        ['car','truck']
    ];
    
    let x = pairsToIndex(data);
    console.log(x);
    
    在浏览器的开发控制台中运行该代码。在挖掘对象
    x
    时,您会注意到每个“子对象”的行为就像指向
    x
    的另一个顶级属性的符号链接。实际上,每个“子”都是指向该对象内其他地方的入口。通过引用传递的使用为我们设置了步骤2


  • 通过以深度优先模式递归遍历该对象并返回每个节点的
    属性来序列化该对象
  • 下面是一个简短的例子:

    function listNode(node) {
        return Array.prototype.concat.apply( [node.key] , node.children.map(listNode) );
    }
    
    let out = listNode(x['']); // choosing the entry point to the hierarchy
    console.log(out);
    
    注意,我不得不使用
    apply
    来避免创建一堆嵌套的单元素数组(即使它们的顺序正确)。这可以用
    \uuu0.flatte
    之类的东西来解决,但在这种情况下,对该语言了解多一点就不需要整个库了

    还要注意,
    listNode
    在技术上是在层次结构的子树上操作的。我告诉它从“根”节点开始,您建议它在原始数据集中由空字符串标识。但是,您可以要求它通过传递不同的起点来序列化树的子集,例如
    listNode(x['cat'])
    listNode(x['fish'])

    最后,该算法是无限递归的。如果向脚本提供非常大的数据集,浏览器将停止该脚本。其他JS环境(比如nodejs或react native)不会这样做


    此时,
    out
    是一个数组,按您希望的顺序列出原始
    数据
    数组中的每个值