【问题标题】:Group Array of objects into specific format using lodash使用 lodash 将对象数组分组为特定格式
【发布时间】:2018-08-01 11:47:34
【问题描述】:

我有这个对象数组,我需要对其进行修改以使渲染更容易。我使用了类似问题中提到的一些代码: Group array of object nesting some of the keys with specific names

这是我的数组和代码

function groupAndMap(events, Year, Month, predic){
    return _.map(_.groupBy(events,Year), (obj,key) => ({
        [Year]: key,
        [Month]: (predic && predic(obj)) || obj
    }));
}

const items = [
{	
    "Year": 2018,
    "Month": 7,
    "Day": 2,
    "Title": "event1",
    "StartDate": "2018-07-02T10:00:00.000Z",
    "EndDate": "2018-07-02T11:00:00.000Z"
}, {
    "Year": 2018,
    "Month": 8,
    "Day": 31,
    "Title": "event2",
    "StartDate": "2018-07-31T10:00:00.000Z",
    "EndDate": "2018-08-02T11:00:00.000Z"
}
   
    
];

function groupAndMap(items, itemKey, childKey, predic){
    return _.map(_.groupBy(items,itemKey), (obj,key) => ({
        [itemKey]: key,
        [childKey]: (predic && predic(obj)) || obj
    }));
}

var result = groupAndMap(items,"Year","Months",
                  arr => groupAndMap(arr,"Month", "Days"));

var jsonvalue = JSON.stringify(result);
document.write(jsonvalue);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>

我希望我的输出采用以下格式

[{
	"Year": "2019",
	"Months": [{
		"Month": "8",
		"Days": [{
			"Day": "31",
			"Events": [{
				"Year": 2019,
				"Month": 8,
				"Day": 31,
				"Title": "event3",
				"StartDate": "2018-07-31T10:00:00.000Z",
				"EndDate": "2018-08-02T11:00:00.000Z"
			}]
		}]
	}]
}]

我应该如何修改代码以获得这个结果?

【问题讨论】:

    标签: javascript arrays format grouping lodash


    【解决方案1】:

    您可以使用带有键的数组来为嵌套对象分组。

    function groupAndMap(events, groups) {
        return _(events)
            .groupBy(groups[0])
            .map((array, key) => ({
                [groups[0]]: key,
                [groups[1] + 's']: groups[2] && groupAndMap(array, groups.slice(1)) || array
            }))
            .values();          
    }
    
    var items = [{ Year: 2018, Month: 7, Day: 2, Title: "event1", StartDate: "2018-07-02T10:00:00.000Z", EndDate: "2018-07-02T11:00:00.000Z" }, { Year: 2018, Month: 8, Day: 31, Title: "event2", StartDate: "2018-07-31T10:00:00.000Z", EndDate: "2018-08-02T11:00:00.000Z" }],
        result = groupAndMap(items, ["Year", "Month", "Day", "Event"]);
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>

    为结果定义了键

    function groupAndMap(events, groups, keys) {
        return _(events)
            .groupBy(groups[0])
            .map((array, key) => ({
                [groups[0]]: key,
                [groups[1] + 's']: groups[2] && groupAndMap(array, groups.slice(1), keys) || _.map(array, o => _.pick(o, keys))
            }))
            .values();          
    }
    
    var items = [{ Year: 2018, Month: 7, Day: 2, Title: "event1", StartDate: "2018-07-02T10:00:00.000Z", EndDate: "2018-07-02T11:00:00.000Z" }, { Year: 2018, Month: 8, Day: 31, Title: "event2", StartDate: "2018-07-31T10:00:00.000Z", EndDate: "2018-08-02T11:00:00.000Z" }],
        result = groupAndMap(items, ["Year", "Month", "Day", "Event"], ['Title', 'StartDate', 'EndDate']);
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>

    【讨论】:

    • 您知道如何从事件数组中省略年、月和日键吗? @NinaScholz
    【解决方案2】:

    我认为如果您按一系列标准分组,这是最简单的:

    const entries = Symbol.for("entries");
    const tree = { [entries]: [] };
    const groups = ["Year", "Month", "Day"];
    const childNames = ["Months", "Days", "Events"];
    
    for(const item of items) {
      let node = tree;
      for(const [index, group] of groups.entries()) {
        const childName = childNames[index];
        const key = item[group];
        if(node[key]) {
          node = node[key];
        } else {
          const children = [];          
          node[entries].push({
              [group]: key,
              [childName]: children
          });
          node = node[key] = { [entries]: children };
        }
      }
      node[entries].push(item);
    }
    
    const result = tree[entries];
    

    这允许您以如下方式访问事件:

     for(const event of tree[2017][12][31][entries])
    

    result 包含您需要的数据结构。

    【讨论】:

      猜你喜欢
      • 2016-08-06
      • 1970-01-01
      • 1970-01-01
      • 2019-01-26
      • 1970-01-01
      • 2019-04-18
      • 2019-08-09
      相关资源
      最近更新 更多