Альтернативный способ сопоставления значений ключей объекта

1

Каков альтернативный/лучший способ сопоставления значений ключа объекта без использования forEach?

Это то, что у меня есть сейчас:

sortObject(source) {
    const object = Object.assign({}, source);

    Object.keys(object).forEach(key => {
      // Sort array by priority (the higher the number, the higher the priority)
      object[key] = object[key].sort((a, b) => b.priority - a.priority);

      // Limit the array length to the 5
      if (object[key].length > 5) {
        object[key] = object[key].slice(0, 5);
      }
    });

    return object;
}

source - это объект, например:

{
  base: [
    { id: 1, priority: 5 },
    { id: 2, priority: 10 },
    { id: 3, priority: 1 },
    { id: 4, priority: 5 },
    { id: 5, priority: 15 }
  ],
  extra: [
    { id: 1, priority: 1 },
    { id: 2, priority: 5 },
    { id: 3, priority: 10 }
  ],
  additional: [
    { id: 1, priority: 5 },
    { id: 2, priority: 10 },
    { id: 3, priority: 10 },
    { id: 4, priority: 15 },
    { id: 5, priority: 1 },
    { id: 6, priority: 29 },
    { id: 7, priority: 100 },
    { id: 8, priority: 100 },
    { id: 9, priority: 5 }
  ]
}

Конечный результат выглядит так:

{
  base: [
    { id: 5, priority: 15 },
    { id: 2, priority: 10 },
    { id: 1, priority: 5 },
    { id: 4, priority: 5 },
    { id: 3, priority: 1 }
  ],
  extra: [
    { id: 3, priority: 10 },
    { id: 2, priority: 5 },
    { id: 1, priority: 1 }
  ],
  additional: [
    { id: 7, priority: 100 },
    { id: 8, priority: 100 },
    { id: 6, priority: 29 },
    { id: 4, priority: 15 },
    { id: 2, priority: 10 }
  ]
}

есть ли лучший/более чистый способ сделать это?

  • 1
    Можете ли вы привести пример фактического ввода вместо пустых объектов-заполнителей, чтобы у нас был минимальный воспроизводимый пример, с которым можно поиграть?
  • 0
    @CertainPerformance уверен! погоди
Показать ещё 2 комментария
Теги:

2 ответа

2
Лучший ответ

Я бы посмотрел на Object.entries (новый как на ES2017, но полиполняемый) и разрушил в цикле for-of loop.

Если ничто иное не имеет доступа к массивам на source (что я, как правило, предполагаю, поскольку sort работает на месте, поэтому код уже изменяет исходный массив, но в то же время source поступает извне, поэтому... ):

sortObject(source) {
    const object = Object.assign({}, source);

    for (const [key, array] of Object.entries(object)) {
        array.sort((a, b) => b.priority - a.priority);
        array.length = Math.min(array.length, 5);
    }

    return object;
}

Если что-то еще имеет доступ к этим массивам, и вы не должны изменять их, кроме их сортировки, тогда вам понадобится ваша первоначальная проверка length и slice:

sortObject(source) {
    const object = Object.assign({}, source);

    for (const [key, array] of Object.entries(object)) {
        array.sort((a, b) => b.priority - a.priority);
        if (array.length > 5) {
            object[key] = array.slice(0, 5);
        }
    }

    return object;
}

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

sortObject(source) {
    const object = Object.assign({}, source);

    for (const [key, array] of Object.entries(object)) {
        object[key] = array = array.slice();
        array.sort((a, b) => b.priority - a.priority);
        array.length = Math.min(array.length, 5);
    }

    return object;
}

Вы можете заменить

        object[key] = array = array.slice();
        array.sort((a, b) => b.priority - a.priority);

с

        object[key] = array = Array.from(array).sort((a, b) => b.priority - a.priority);

если вам нравится, но это будет использовать итератор, что больше накладных расходов, чем slice.

0

Вы также можете использовать карту для циклизации записей объекта и сращивания для отсечения длины массива:

const getSortedObj = (source) => {
    let obj = Object.assign({}, source);
    Object.entries(obj).map( entry => {
        let [key, arr] = entry;
        arr.sort((a, b) => b.priority - a.priority).splice(Math.min(arr.length, 5));
        return entry;
    });
    return obj;
};
  • 0
    Это неправильное использование map . map строит и возвращает массив. Если вы не используете возвращаемое значение map (массив, который она создает) и не хотите использовать for-of , используйте forEach .
  • 0
    Я не согласен. Почему это мисс карта? и вопрос в том, что является альтернативным / лучшим способом для отображения через ключ-значения объекта без использования forEach?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню