使用lodash根据类型对多个对象进行分组 [英] Group Multiple Objects Based on Type Using lodash

查看:181
本文介绍了使用lodash根据类型对多个对象进行分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将unordered-list-itemordered-list-item分组.

下面是原始结构:

{
  data: {
    areas: [{
      sections: [{
        rjf: [
          {
            type: "unordered-list-item",
            text: "Item 1",
          },
          {
            type: "unordered-list-item",
            text: "Item 2",
          },
          {
            type: "paragraph",
            text: "This is text",
          }]
      }]
    }]
  }
}

现在,我要将所有列表项分组到一个新对象中.

Now I want to group all list items into a new object.

所以预期的结构是:

{
  data: {
    areas: [{
      sections: [{
        rjf: [
          {
            type: "list",
            items: [{
              type: "unordered-list-item",
              text: "Item 1",
            },
            {
              type: "unordered-list-item",
              text: "Item 2",
            }]
          },
          {
            type: "paragraph",
            text: "This is text",
          }]
      }]
    }]
  }
}

所以我想将所有unordered-list-item and ordered-list-item移到items数组,并且不影响以下对象type(如paragraph).

So I wanted to move all the unordered-list-item and ordered-list-item to items array and the following object type like paragraph shouldn't be impacted.

我用TypeScript创建了一个解决方案,但是代码太长了:

I created a solution in TypeScript, but the code was too long:

const areas = data.areas;
      const listItemTypes = ['unordered-list-item', 'ordered-list-item'];
      return areas.map(area => {
        return area.sections.map(section => {
          let lastHeadingIndex = -1;
          return section.rjf.reduce((acc, current, index) => {
            if (!current.type || !listItemTypes.includes(current.type)) {
              lastHeadingIndex = acc.length;
              return [...acc, current];
            }
            let listObject = acc.find((el, i) => i > lastHeadingIndex && i < index && el.type === 'list');
            if (!listObject) {
              listObject = {
                type: 'list',
                items: [current]
              };
              return [...acc, listObject];
            }
            listObject.items = [...listObject.items, current];
            return acc;
          }, []);
        });
      });

如何使用lodash实现相同的功能?

****更新****

****UPDATE****

我尝试过lodash,但似乎没有用.

I tried with lodash, but dosen't seems to work.

var content = {
  data: {
    areas: [{
      sections: [{
        rjf: [{
            type: "unordered-list-item",
            text: "Item 1",
          },
          {
            type: "unordered-list-item",
            text: "Item 2",
          },
          {
            type: "paragraph",
            text: "This is text",
          }
        ]
      }]
    }]
  }
};

var result = content.data.areas.map((area => {
    return area.sections.map(section => {
       section.rfj = _.groupBy(section.rfj, 'type');
    });
}));

document.body.innerHTML = '<pre>' + JSON.stringify(result, null, '  ') + '</pre>';

<script src="https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js"></script>

推荐答案

您可以使用另一种方法,即复制每个对象leven并映射所有数组,并使用分组函数将最后一级分组.

You could use another approach by copying each object leven and map all arrays and group the last level by using a function for grouping.

此方法使用amit函数,该函数获取每个级别和起始对象的所有功能.

This approach uses am iter function which gets all functions for each level and the starting object.

最后,它将返回具有给定结构和分组项目的新对象.

At the end, it returnes a new object with the given structure and the grouped items.

function copy(source, fn) {
    return Object.assign({}, ...Object
        .entries(source)
        .map(([k, v]) => ({ [k]: fn(v) }))
    );
}

function map(array, fn) {
    return array.map(fn);
}

function group(array) {
    var items;
    return array.reduce((r, o) => {
        if (listItemTypes.includes(o.type)) {
            if (!items) {
                items = [];
                r.push({ type: 'list', items });
            }
            items.push(o);
        } else {
            items = undefined;
            r.push(o);
        }
        return r;
    }, []);
}

function iter([fn, ...fns], object) {
    return fn ? fn(object, iter.bind(null, fns)) : object;
}    

var object = { data: { areas: [{ sections: [{ rjf: [{ type: "unordered-list-item", text: "Item 1" }, { type: "unordered-list-item", text: "Item 2" }, { type: "paragraph", text: "This is text" }] }] }] } },
    listItemTypes = ['unordered-list-item', 'ordered-list-item'],
    result = iter([copy, copy, map, copy, map, copy, group], object);

console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }

这篇关于使用lodash根据类型对多个对象进行分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆