-2

I have the next array structure:

const arr = [
   {
      label: 'Apple',
      data: [{test: '1'}, {test: '2'}],
      collapsedData: [{test: '1'}, {test: '2'}],

   },
   {
      label: 'Orange',
      data: [{test: '3'}, {test: '4'}],
      collapsedData: [{test: '3'}, {test: '4'}],
   },
   {
      label: 'Tomato',
      data: [{test: '5'}, {test: '6'}],
      collapsedData: [{test: '5'}, {test: '6'}],

   },
   {
      label: 'Banana',
      data: [{test: '7'}, {test: '8'}],
      collapsedData: [{test: '7'}, {test: '8'}],
   }
]

I also have a method to sort an array - sortArr - sorts an array by alphabet.

I need to iterate over arr and apply sortArr to data and collapsedData if the label is Apple.

So, data and collapsedData should be sorted for Apple label.

Desired output:

const outputArr = [
   {
      label: 'Apple',
      data: [{test: '2'}, {test: '1'}],
      collapsedData: [{test: '2'}, {test: '1'}],

   },
   {
      label: 'Orange',
      data: [{test: '3'}, {test: '4'}],
      collapsedData: [{test: '3'}, {test: '4'}],
   },
   {
      label: 'Tomato',
      data: [{test: '5'}, {test: '6'}],
      collapsedData: [{test: '5'}, {test: '6'}],

   },
   {
      label: 'Banana',
      data: [{test: '7'}, {test: '8'}],
      collapsedData: [{test: '7'}, {test: '8'}],
   }
]

What can be the solution?

lecham
  • 2,294
  • 6
  • 22
  • 41

2 Answers2

1

Take a look on below:

function sortExceptApples(arr){
    for (let i = 0; i < arr.length; i++)
      if (arr[i].label !== "Apple")
        arr[i] = { ...arr[i], data: sortArr(arr[i].data), collapsedData: sortArr(arr[i].collapsedData) }
 return arr
}

and then:

let outputArr = sortExceptApples(arr)
1

As per your question

I need to iterate over arr and apply sortArr to data and collapsedData if the label is Apple.

  1. First filter your arr with arr.filter(x => x.label == 'Apple') to get only Apple record.
  2. Then loop over it with forEach and sort your inner object data & collapsedData
  3. Keep in mind that data is array of object, so need to filter with its property value like a.test. I've attached + before a.test which will convert value to number.

You can check output below.

const arr = [
  {
    label: 'Apple',
    data: [{test: '2'}, {test: '1'}],
    collapsedData: [{test: '2'}, {test: '1'}],

  },
  {
    label: 'Orange',
    data: [{test: '3'}, {test: '4'}],
    collapsedData: [{test: '3'}, {test: '4'}],
  },
  {
    label: 'Tomato',
    data: [{test: '5'}, {test: '6'}],
    collapsedData: [{test: '5'}, {test: '6'}],

  },
  {
    label: 'Banana',
    data: [{test: '7'}, {test: '8'}],
    collapsedData: [{test: '7'}, {test: '8'}],
  }
];

const t = () => {
    arr.filter(x => x.label == 'Apple')
        .forEach(x => {
          x.data.sort((a,b) => +a.test - +b.test);
          x.collapsedData.sort((a,b) => +a.test - +b.test);
        });
    return arr;
}        
console.log(t());
Karan
  • 12,059
  • 3
  • 24
  • 40
  • What does this function return? If I use it like this: const t = () => { return arr.filter(x => x.label == 'Apple') .forEach(x => { x.data.sort((a,b) => +a.test - +b.test); x.collapsedData.sort((a,b) => +a.test - +b.test); }) }; it returns undefined – lecham May 22 '20 at 10:52
  • `forEach` will not return anything, so you are getting `undefined. You need to add `return arr;` to next line. Then it will work you've expected. Also I have updated my answer. – Karan May 22 '20 at 11:10
  • `filter` will return `array` but `forEach` won't return anything. So you can do like `const filteredArr = arr.filter(...);` and then `filteredArr.forEach(...)`. Then `return filteredArr;`. – Karan May 22 '20 at 11:28