-3

I have array of object and it has in another array of obj, how to sort this array depend on equal actionId key in the inside array?

so this my original array:

const arrayOfItems = {
    items: [
        {
            item: '1',
            anotherArray: [{ actionId: '1234-dh4t-tr21-6sw8' }]
        },
        {
            item: '2',
            anotherArray: []
        },
        {
            item: '3',
            anotherArray: []
        },
        {
            item: '4',
            anotherArray: [{ actionId: '1234-dh4t-tr21-6sw8' }]
        },
        {
            item: '5',
            anotherArray: []
        },
        {
            item: '6',
            anotherArray: [{ actionId: '1234-dh4t-tr21-6sw8' }]
        }
    ]
};

the result should be all items that has the same actionId under each other

sortedArray = {
    items: [
    {
       item: '1',
       anotherArray: [{ actionId: '1234-dh4t-tr21-6sw8' }]
    },
    {
      item: '4',
      anotherArray: [{ actionId: '1234-dh4t-tr21-6sw8' }]
    },
    {
      item: '6',
      anotherArray: [{ actionId: '1234-dh4t-tr21-6sw8' }]
    },
    ...
]
};

This is what I tried:

const sortingArray = arrayOfItems.items.sort((a, b) => {
  return a.anotherArray > 0 && a.anotherArray[0].actionId.localeCompare(b.anotherArray[0].actionId);
})
Y Allaban
  • 112
  • 1
  • 1
  • 8
  • 1
    The posted question does not appear to include any attempt at all to solve the problem. Stack Overflow expects you to [try to solve your own problem first](https://meta.stackoverflow.com/questions/261592/), as your attempts help us to better understand what you want. Please edit the question to show what you've tried, so as to illustrate a specific roadblock you're running into in a [MCVE]. For more information, please see [ask] and take the [tour]. – CertainPerformance Oct 04 '19 at 23:29
  • 1
    There are literally countless tutorials on the web for exactly this scenario to help you with your homework with just a quick search. Cheers. – Chris W. Oct 04 '19 at 23:36
  • @ChrisW. I looked for that But I couldn't found, could you please write me url – Y Allaban Oct 04 '19 at 23:44
  • `a.discounts > 0` should be `a.discounts.length > 0`. – Barmar Oct 04 '19 at 23:45
  • I don't think you can do this with `sort()`. The comparison function can only specify the relative order of elements, it can't force them to be grouped together. – Barmar Oct 04 '19 at 23:50
  • Thanks @Barmar, for your help, could you please give me a hint where to look or what to use ? – Y Allaban Oct 04 '19 at 23:56
  • I think you'll have to write your own loop that does it, there's nothing built-in for it. You could create an object whose keys are `actionId` and values are arrays of the objects. – Barmar Oct 05 '19 at 00:05
  • See https://stackoverflow.com/questions/24302630/how-combine-the-array-in-javascript/24302781#24302781 for the general approach. – Barmar Oct 05 '19 at 00:05
  • So, in the first code snippet, anotherArray is named discounts right? – Kostas Minaidis Oct 05 '19 at 00:23
  • @KostasX , sorry i update the code snippet – Y Allaban Oct 05 '19 at 00:27
  • Would something like this work for you? https://codepen.io/kostasx/pen/WNNNrRN?editors=0011 – Kostas Minaidis Oct 05 '19 at 00:35

1 Answers1

1

Something like this does the trick. This sorts based upon ActionId, then item. Items without an actionId will be moved to the end of the array.

const arrayOfItems = {items: [{item: '1', anotherArray: [{actionId: '1234-dh4t-tr21-6sw8'}]}, {item: '2', anotherArray: []}, {item: '3', anotherArray: []}, {item: '4', anotherArray: [{actionId: '1234-dh4t-tr21-6sw8'}]}, {item: '5', anotherArray: []}, {item: '6', anotherArray: [{actionId: '1234-dh4t-tr21-6sw8'}]}]};

arrayOfItems.items.sort((a, b) => {
  const lenA = a.anotherArray.length,
        lenB = b.anotherArray.length;

  // order based on item if both a and b don't have an actionId
  if (!lenA && !lenB) return a.item - b.item;
  // move the element without actionId towards the end if a or b doesn't have an actionId
  if (!lenA || !lenB) return lenB - lenA;

  const actionIdA = a.anotherArray[0].actionId,
        actionIdB = b.anotherArray[0].actionId;

  // order based on item if both a and b have the same actionId
  if (actionIdA === actionIdA) return a.item - b.item;

  // order based on actionId
  return actionIdA.localeCompare(actionIdB);
});

console.log(arrayOfItems.items);

If you don't care about ordering by item second, you can remove:

// order based on item if both a and b don't have an actionId
if (!lenA && !lenB) return a.item - b.item;

And:

// order based on item if both a and b have the same actionId
if (actionIdA === actionIdA) return a.item - b.item;
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
  • what if we have different actionId, it will not sort them correctly – Y Allaban Oct 05 '19 at 01:40
  • @YAllaban It places elements with the same *actionId* under each other. So if you have action ids `["a", "b", "b", "a", "a"]` they will be sorted as `["a", "a", "a", "b", "b"]`. Followed by the elements without *actionId*. – 3limin4t0r Oct 05 '19 at 01:43