0

Can't figure out how to sort this kind of structure:

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

I can only sort by the first level like this: _.sortBy(myArray,'text')

I need something like _.sortBy(myArray, ['text','children.text']) this obviously doesn't work.

I need to sort by children.text of each item.

4
  • Do you want to sort the children array of each object? Commented Aug 2, 2019 at 14:37
  • Or do you want to sort the array myArray based on the first index of the array children? Commented Aug 2, 2019 at 14:38
  • First I want to sort first level, I already done this like this: _.sortBy(myArray,'text') but additionally, I need to sort children of each first level item. Commented Aug 2, 2019 at 14:40
  • So, of the first level has two items with the same text, do the children then affect how that top level is sorted? Commented Aug 2, 2019 at 14:53

3 Answers 3

1

You should loop over the children array.

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>

Sign up to request clarification or add additional context in comments.

Comments

1

If you need to sort by the 1st item of the children array, you can use '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>

If you need to sort the children, and then use the 1st item, you can generate a function with _.flow(). The function starts by mapping each object, and sorting it's children, and then sorts the entire array:

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>

And the same idea but terser with 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>

Comments

0

You can use for loop to trace the children and sort the children array.

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

This code should do like you want or you can create it as function

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

sortParentAndChildren(myArray, "text");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.