Как отсортировать вложенный массив объектов в JavaScript? - PullRequest
4 голосов
/ 13 мая 2019

У меня есть массив объектов:

entities: [
  {
    name: "zBroomsticks PTY",
    id: 34098365,
    entityType: "personal",
    facilities: [
      {
        type: "Home loan",
        account: "032654 987465",
        existing: true,
        modified: "04/12/2018",
        limit: 100000
      },
      {
        type: "Credt card",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018",
        limit: 200000
      },
      {
        type: "Credt card",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018",
        limit: 10000
      },
      {
        type: "Credt card",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018",
        limit: 10000
      }
    ]
  },
  {
    name: "Mr John Doe -3409865, Mrs Jane Doe -34098365",
    id: 34098365,
    entityType: "business",
    facilities: [
      {
        type: "Overdraft",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018" ,
        limit: 10000
      }
    ]
  },
  {
    name: "Mr Jack",
    id: 34098365,
    entityType: "mixed",
    facilities: [
      {
        type: "Overdraft",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018",
        limit: 10000
      }
    ]
  }
]

Я хочу отсортировать это в определенном порядке:

  1. entity.name: в алфавитном порядке возрастания.

  2. entity.entityType: 1. личный 2. бизнес 3. смешанный

  3. entity.facilities.limit: в порядке убывания

Это код, который я получил до сих пор:

sortData(entities) {
    var order = {
      entityType: { personal: 2, business: 1 }
    };

    return entities.map(ent =>
      entities.sort(
        (a, b) =>
          a.name - b.name ||
          order.entityType[a.facilities.entityType] - order.entityType[b.facilities.entityType]
      )
    );
}

Я знаю, как выполнить сортировку имен, но не могу найти подход для 2 и 3?

Ссылка на код

Ответы [ 3 ]

3 голосов
/ 13 мая 2019

Во-первых, для заказа по names вы можете использовать localeCompare () .Во-вторых, в массиве facilities нет свойства entityType, но вы пытаетесь получить к нему доступ.Теперь одно из решений - сначала использовать Array.map () , чтобы получить новый массив, в котором массив facilities упорядочен по свойству limit, затем вы можете отсортировать новый массив, возвращаемый map() сначала names, а затем entityType, что-то вроде этого:

const input = [{name:"zBroomsticks PTY",id:34098365,entityType:"personal",facilities:[{type:"Home loan",account:"032654 987465",existing:true,modified:"04/12/2018",limit:100000},{type:"Credt card",account:"032654 987465",existing:false,modified:"04/12/2018",limit:200000},{type:"Credt card",account:"032654 987465",existing:false,modified:"04/12/2018",limit:10000},{type:"Credt card",account:"032654 987465",existing:false,modified:"04/12/2018",limit:10000}]},{name:"Mr John Doe -3409865, Mrs Jane Doe -34098365",id:34098365,entityType:"business",facilities:[{type:"Overdraft",account:"032654 987465",existing:false,modified:"04/12/2018",limit:10000}]},{name:"Mr Jack",id:34098365,entityType:"mixed",facilities:[{type:"Overdraft",account:"032654 987465",existing:false,modified:"04/12/2018",limit:10000}]},{name:"Mr Jack",id:34098365,entityType:"personal",facilities:[{type:"Overdraft",account:"032654 987465",existing:false,modified:"04/12/2018",limit:10000}]}];

let order = {
  entityType: {personal:1, business:2, mixed:3}
};

function sortData(entities)
{    
    let limitOrder = entities.map(e =>
    {
        e.facilities.sort((a, b) => b.limit - a.limit);
        return e;
    });

    return limitOrder.sort((a, b) =>
    {
        return a.name.localeCompare(b.name) ||
               order.entityType[a.entityType] - order.entityType[b.entityType];
    });
}

console.log(sortData(input));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

Обратите внимание, я продублировал объект, связанный с name: "Mr Jack", используя другой entityType, чтобы вы могли видеть, как работает алгоритм, когда есть два объекта сравняется names.

0 голосов
/ 13 мая 2019

Сортируйте ваш массив по приоритету 1, 2 и, наконец, 3

2, вы можете использовать объект index для отображения entityType с их весом.

3 Поскольку вы хотите отсортировать по descending order, вы найдете минимальное значение limit в списке facilities и сравните его с другим элементом.

let entities = [
  {
    name: "zBroomsticks PTY",
    id: 34098365,
    entityType: "personal",
    facilities: [
      {
        type: "Home loan",
        account: "032654 987465",
        existing: true,
        modified: "04/12/2018",
        limit: 100000
      },
      {
        type: "Credt card",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018",
        limit: 200000
      },
      {
        type: "Credt card",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018",
        limit: 10000
      },
      {
        type: "Credt card",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018",
        limit: 10000
      }
    ]
  },
  {
    name: "Mr John Doe -3409865, Mrs Jane Doe -34098365",
    id: 34098365,
    entityType: "business",
    facilities: [
      {
        type: "Overdraft",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018",
        limit: 10000
      }
    ]
  },
  {
    name: "Mr Jack",
    id: 34098365,
    entityType: "mixed",
    facilities: [
      {
        type: "Overdraft",
        account: "032654 987465",
        existing: false,
        modified: "04/12/2018",
        limit: 10000
      }
    ]
  }
];


const entityIndex = { personal: 1, business: 2, mixed: 3 };

let result = entities.sort((a, b) => {
  if (a.name > b.name) return -1;
  if (a.name < b.name) return 1;

  let et = entityIndex[a.entityType] - entityIndex[b.entityType];
  if (et != 0) return et;

  const aMinLimit = Math.min(...a.facilities.map(i => i.limit));
  const bMinLimit = Math.min(...b.facilities.map(i => i.limit));

  return bMinLimit - aMinLimit;

})

console.log(JSON.stringify(result));
0 голосов
/ 13 мая 2019

1001 * попробовать *

eType = {personal:1, business:2, mixed:3};

entities.sort((a,b) => {
   if(a.name>b.name) return 1;
   if(a.name<b.name) return -1;

   let et=eType[a.entityType]-eType[b.entityType];
   return et;   
})

entities.forEach(e=> e.facilities.sort((a,b)=> b.limit - a.limit ))

let entities = [
        {
          name: "zBroomsticks PTY",
          id: 34098365,
          entityType: "personal",
          facilities: [
            {
              type: "Home loan",
              account: "032654 987465",
              existing: true,
              modified: "04/12/2018",
              limit: 100000
            },
            {
              type: "Credt card",
              account: "032654 987465",
              existing: false,
              modified: "04/12/2018",
              limit: 200000
            },
            {
              type: "Credt card",
              account: "032654 987465",
              existing: false,
              modified: "04/12/2018",
              limit: 10000
            },
            {
              type: "Credt card",
              account: "032654 987465",
              existing: false,
              modified: "04/12/2018",
              limit: 10000
            }
          ]
        },
        {
          name: "Mr John Doe -3409865, Mrs Jane Doe -34098365",
          id: 34098365,
          entityType: "business",
          facilities: [
            {
              type: "Overdraft",
              account: "032654 987465",
              existing: false,
              modified: "04/12/2018" ,
              limit: 10000
            }
          ]
        },
{
          name: "Mr Jack",
          id: 34098365,
          entityType: "mixed",
          facilities: [
            {
              type: "Overdraft",
              account: "032654 987465",
              existing: false,
              modified: "04/12/2018",
              limit: 10000
            }
          ]
        }
      ];
      
      
eType = {personal:1, business:2, mixed:3};

entities.sort((a,b) => {
   if(a.name>b.name) return 1;
   if(a.name<b.name) return -1;
   
   let et=eType[a.entityType]-eType[b.entityType];
   return et;   
})

entities.forEach(e=> e.facilities.sort((a,b)=> b.limit - a.limit ))

console.log(entities);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...