JS Сортировка превосходящего массива объектов в зависимости от значения объекта с использованием lodash - PullRequest
0 голосов
/ 24 мая 2018

У меня следующая структура:

let drives = [
    {id: 1, moves:[
        {moveId: 1, difference: 1},
        {moveId: 2, difference: 2}]
    },
    {id: 2, moves:[
        {moveId: 1, difference: -2}]
    },
    {id: 3, moves:[
        {moveId: 1, difference: 5}, 
        {moveId: 2, difference: 2}, 
        {moveId: 3, difference: 4}]
    },
    {id: 4, moves:[
        {moveId: 1, difference: 6}]
    }
]

Теперь я хочу отсортировать массив дисков по разнице хода. Результат должен быть примерно таким (в зависимости от порядка сортировки).

let drives = [
    {id: 2, moves:[
        {moveId: 1, difference: -2}]
    },
    {id: 1, moves:[
        {moveId: 1, difference: 1},
        {moveId: 2, difference: 2}]
    },
    {id: 3, moves:[
        {moveId: 2, difference: 2},
        {moveId: 3, difference: 4},
        {moveId: 1, difference: 5}]
    },
    {id: 4, moves:[
        {moveId: 1, difference: 6}]
    }
]

Я пытался сделать это с помощью lodash, используя этот код

_.orderBy(drives, 'moves.difference', 'asc');

Но это, похоже, ничего не делает.У кого-нибудь есть идеи, как с этим справиться?

Ответы [ 4 ]

0 голосов
/ 24 мая 2018

У вашей ситуации есть 2 решения, как я понимаю.Чтобы найти решение, которое вам нужно, вам нужно выбрать метод ранжирования ваших дисков.К сожалению, ваш метод может привести к неожиданным результатам в будущем.

Вы обнаружите, что при перемещении будут повторяться значения разностей, и в этой ситуации вам нужно решить, какой из дисков будет иметь больший вес в алгоритме сортировки.

Ниже вы можете найти строящийся объект rankMap с наибольшим и наименьшим различием между дисками, чтобы позже помочь вам отсортировать массив.

Надеюсь, это поможет

    let drives = [
    {id: 1, moves:[
        {moveId: 1, difference: 1},
        {moveId: 2, difference: 2}]
    },
    {id: 2, moves:[
        {moveId: 1, difference: -2}]
    },
    {id: 3, moves:[
        {moveId: 1, difference: 5}, 
        {moveId: 2, difference: 2}, 
        {moveId: 3, difference: 4}]
    }
];

// we build a rankMap by which we will later sort the array of objects
let rankMap = {};

drives = drives.map(drive => {
    let
        biggestDiff = null,
        smallestDiff = null;

    let moves = _.orderBy(drive.moves, move => {
        if(biggestDiff < move.difference || biggestDiff === null) {
            biggestDiff = move.difference;
        }
        if(smallestDiff > move.difference || smallestDiff === null) {
            smallestDiff = move.difference;
        }

        return move.difference;
    }, ['asc']);

    rankMap[drive.id] = {
        smallestDiff: smallestDiff,
        biggestDiff: biggestDiff
    };

    return Object.assign({}, drive, {
        moves: moves
    });
});

let
    sortedByBiggestDifference = _.orderBy(drives, drive => rankMap[drive.id].biggestDiff, ['asc']),
    sortedBySmallestDifference = _.orderBy(drives, drive => rankMap[drive.id].smallestDiff, ['asc']);

console.log(drives);
console.log(sortedByBiggestDifference);
console.log(sortedBySmallestDifference);
0 голосов
/ 24 мая 2018

Вы можете отсортировать дважды.Сначала отсортируйте массив moves.После того, как весь массив moves отсортирован.Затем выполните сортировку по значению difference в первом индексе.

let drives = [ {id: 1, moves:[ {moveId: 1, difference: 1}, {moveId: 2, difference: 2}] }, {id: 2, moves:[ {moveId: 1, difference: -2}] }, {id: 3, moves:[ {moveId: 1, difference: 5}, {moveId: 2, difference: 2}, {moveId: 3, difference: 4}] }, {id: 4, moves:[{moveId: 1, difference: 6}] } ];
drives.forEach(o => o.moves.sort((a,b) => a.difference - b.difference));
drives.sort((a,b) => a.moves[0].difference - b.moves[0].difference);
console.log(drives);
0 голосов
/ 24 мая 2018

Вы можете использовать вложенный подход, отсортировав внутренний moves, а затем внешний ход, взяв первый элемент для сортировки.

var drives = drives = [{ id: 1, moves: [{ moveId: 1, difference: 1 }, { moveId: 2, difference: 2 }] }, { id: 2, moves: [{ moveId: 1, difference: -2 }] }, { id: 3, moves: [{ moveId: 1, difference: 5 }, { moveId: 2, difference: 2 }, { moveId: 3, difference: 4 }] }, { id: 4, moves: [{ moveId: 1, difference: 6 }] }];

console.log(
    _(drives)
         .map(o => Object.assign({}, o, { moves: _.sortBy(o.moves, 'difference') }))
         .sortBy(({ moves: [{ difference }] }) => difference)
         .value()
);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
0 голосов
/ 24 мая 2018

Ваш вопрос, кажется, должен быть решен на две части.Для первой части сначала отсортируйте свой собственный массив, чтобы ответ был следующим:

let drives = [
      {id: 1, moves:[
               {moveId: 1, difference: 1},
               {moveId: 2, difference: 2}]
      },
      {id: 2, moves:[
               {moveId: 1, difference: -2}]
      },
      {id: 3, moves:[
               {moveId: 1, difference: 5}, 
               {moveId: 2, difference: 2}, 
               {moveId: 3, difference: 4}]
      }
    ]

    drives.forEach(x=> {
	    x.moves.sort(function (a, b) {
        return a.difference - b.difference;
      });
    });

    drives.sort(function (a, b) {
      return a.moves[0].difference - b.moves[0].difference;
    });
    
    console.log(drives);

Что касается второй части, я не уверен, каково ваше состояние для переключения между id 2 и id 1.

let drives = [
  {id: 1, moves:[
       {moveId: 1, difference: 1},
       {moveId: 2, difference: 2}]
  },
  {id: 2, moves:[
       {moveId: 1, difference: -2},
       {moveId: 2, difference: 4}]
  }]

Если для вышеслучаях, id:2 будет первым или останется той же последовательностью?

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