javascript - 如何使用 Underscore.js 从平面列表创建嵌套对象?

标签 javascript recursion nested underscore.js grouping

给出输入订单:

input = [
    {
        "top": "peach", 
        "middle": "monkey",
        "bottom": "blue"
    },
    {
        "top": "peach", 
        "middle": "monkey",
        "bottom": "red"
    },
    {
        "top": "peach", 
        "middle": "cat",
        "bottom": "brown"
    },
    {
        "top": "peach", 
        "middle": "cat",
        "bottom": "black"
    },
    {
        "top": "peach", 
        "middle": "dog",
        "bottom": "purple"
    }
];

order = ["top", "middle", "bottom"];

生成“嵌套”输出:

output =     {
    "name": "peach",
    "children": [
        {
            "name": "monkey",
            "children": [
                { "name": "blue" },
                { "name": "red" }
            ]
        },
        {
            "name": "cat",
            "children": [
                { "name": "brown" },
                { "name": "black" }
            ]
        },
        {
            "name": "dog",
            "children": [
                { "name": "purple" }
            ]
        }
    ]
};

我知道它与 _.groupBy() 和使用递归有关,但我无法理解它......

最佳答案

这是一个递归解决方案,使用 groupBy 订单列表中的每个项目:

var nestedGroup = function(list, order) {

    if( _.isEmpty(order)) return [];

    var groups = _.groupBy(list, _.first(order));

    return _.map(groups, function(children, key){
        var group = {
            name: key,
            children: nestedGroup(children, _.rest(order))
        };

        return _.isEmpty(group.children) ? _.omit(group, 'children') : group;
    });
}

var groups = nestedGroup(input, order);

angular.module('MyModule', [])

.controller('MyController', function( $scope ) {
  
	var input = [
	    {
	        "top": "peach", 
	        "middle": "monkey",
	        "bottom": "blue"
	    },
	    {
	        "top": "peach", 
	        "middle": "monkey",
	        "bottom": "red"
	    },
	    {
	        "top": "peach", 
	        "middle": "cat",
	        "bottom": "brown"
	    },
	    {
	        "top": "peach", 
	        "middle": "cat",
	        "bottom": "black"
	    },
	    {
	        "top": "peach", 
	        "middle": "dog",
	        "bottom": "purple"
	    }
	];

	var order = ["top", "middle", "bottom"];

	var nestedGroup = function(list, order) {

		if( _.isEmpty(order)) return [];

		var groups = _.groupBy(list, _.first(order));

		return _.map(groups, function(children, key){
			var group = {
				name: key,
				children: nestedGroup(children, _.rest(order))
			};

			return _.isEmpty(group.children) ? _.omit(group, 'children') : group;
		});
	}

	var groups = nestedGroup(input, order);
  
    $scope.groups = groups;
});

  
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>

<div ng-app='MyModule' ng-controller='MyController'>
  <p>{{groups || json}}</p>
</div>

关于javascript - 如何使用 Underscore.js 从平面列表创建嵌套对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26861471/

相关文章:

Javascript - 无尽的递归函数

c - 在c中交换反转链表

javascript - 从 : Intent shows a blank screen on a real device and I do not get any error with adb logcat 开始

解析不同参数对象的Javascript泛型方法

scala - 无法优化@tailrec注释的方法循环: it contains a recursive call not in tail position

java - 使用 JAXB 编码嵌套对象 - 展开

recursion - 重新创建一棵扁平的树

java - 如何使用Java中的嵌套循环仅打印一次单个数字?

javascript - 如何使用 JQuery 按属性删除元素

javascript - 如何将新对象插入状态而不删除 React 中以前的值