【问题标题】:ES6, Lodash sortBy 2 level array of objectsES6,Lodash sortBy 2 级对象数组
【发布时间】:2019-08-02 14:35:38
【问题描述】:

不知道如何对这种结构进行排序:

[
  0: { text: 'Lorem', 'children': [ 0: { text: 'Ipsum of Lorem' } ... ] }
  ...
]

我只能像这样按第一级排序:_.sortBy(myArray,'text')

我需要_.sortBy(myArray, ['text','children.text']) 之类的东西,这显然行不通。

我需要按每一项的 children.text 排序。

【问题讨论】:

  • 是否要对每个对象的子数组进行排序?
  • 还是要根据数组children的第一个索引对数组myArray进行排序?
  • 首先我想对第一级进行排序,我已经这样做了:_.sortBy(myArray,'text') 但另外,我需要对每个第一级项目的子项进行排序。
  • 那么,第一个级别有两个具有相同文本的项目,孩子们会影响顶级的排序方式吗?

标签: javascript sorting ecmascript-6 lodash


【解决方案1】:

你应该循环遍历 children 数组。

const myArray = [{ text: 'ZLorem', 'children': [{ text: 'Ipsum2' }, { text: 'Apsum2' }] },{ text: 'Lorem', 'children': [{ text: 'Ipsum1' }, { text: 'Zpsum1' }] }],
      result = _.sortBy(myArray, 'text');
      
result.forEach(o => {
  if (o.children) 
    o.children = _.sortBy(o.children, 'text');
});

console.log(result);
.as-console-wrapper { min-height: 100%; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

【讨论】:

    【解决方案2】:

    如果需要按children数组的第一项排序,可以使用'children[0].text'

    const myArray = [
      { text: 'Lorem', 'children': [{ text: 'Ipsum2' }] },
      { text: 'Lorem', 'children': [{ text: 'Ipsum1' }] }
    ]
    
    const result = _.sortBy(myArray, ['text','children[0].text'])
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

    如果你需要对孩子进行排序,然后使用第一项,你可以用_.flow()生成一个函数。该函数首先映射每个对象,并对其进行排序children,然后对整个数组进行排序:

    const { flow, partialRight: pr, map, sortBy } = _
    
    const fn = flow(
      pr(map, o => ({ ...o, children: sortBy(o.children, 'text') })),
      pr(sortBy, ['text','children[0].text'])
    )
    
    const myArray = [
      { text: 'Lorem', 'children': [{ text: 'Ipsum2' }, { text: 'Ipsum4' }] },
      { text: 'Lorem', 'children': [{ text: 'Ipsum3' }, { text: 'Ipsum1' }] }
    ]
    
    const result = fn(myArray)
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

    同样的想法,但用 lodash/fp 更简洁:

    const { flow, map, sortBy } = _
    
    const fn = flow(
      map(o => ({ ...o, children: sortBy('text', o.children) })),
      sortBy(['text','children[0].text'])
    )
    
    const myArray = [
      { text: 'Lorem', 'children': [{ text: 'Ipsum2' }, { text: 'Ipsum4' }] },
      { text: 'Lorem', 'children': [{ text: 'Ipsum3' }, { text: 'Ipsum1' }] }
    ]
    
    const result = fn(myArray)
    
    console.log(result)
    <script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

    【讨论】:

      【解决方案3】:

      您可以使用 for 循环来跟踪子元素并对子数组进行排序。

      _.sortBy(myArray, 'text');
      for(let parent of myArray) {
          _.sortBy(parent.children, 'text');
      }
      

      此代码应该按照您的意愿执行,或者您可以将其创建为函数

      function sortParentAndChildren(myArray, key) {
          _.sortBy(myArray, key);
          for (let parent of myArray) {
              _.sortBy(parent.children, key);
          }
      }
      
      sortParentAndChildren(myArray, "text");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-01-22
        • 1970-01-01
        • 2017-02-22
        • 2015-09-04
        • 1970-01-01
        • 1970-01-01
        • 2020-04-11
        相关资源
        最近更新 更多