#javascript
Вопрос:
У меня есть объект, как показано ниже:
const boxOfFruits = {
apples: [
{
name: "Kashmiri",
},
{
name: "Washington",
},
{
name: "Himalayan",
},
{
name: "Fuji",
}
],
oranges: [
{
name: "Nagpur",
},
{
name: "Clementine",
},
],
mangoes: [
{
name: "Totapuri",
},
{
name: "Alphonso",
},
{
name: "Langda",
},
],
}
Я хочу разделить эти фрукты на коробки; максимум n в каждой, скажем, где n равно 3, а яблоки, апельсины и манго распределены поровну.
Таким образом, результат в этом случае будет:
box_1 = [{name: "Kashmiri"}, {name: "Nagpur"},{name: "Totapuri"}];
box_2 = [{name: "Washington"}, {name: "Clementine"},{name: "Alphonso"}];
box_3 = [{name: "Himalayan"},{name: "Langda"}, {name: "Fuji"}];
Тип фруктов (яблоко, апельсины и т. Д.) / ключей в объекте может увеличиваться / уменьшаться, и n также является переменной. В случае, если общее количество плодов меньше n, то это будет всего 1 коробка фруктов.
Что я пробовал до сих пор:
Используя Lodash, я вычисляю минимальные и максимальные плоды в одном типе:
const minFruitType = _.min(Object.values(basket).map((eachBasket: any) => eachBasket.length));
Общее количество команд будет равно сумме плодов / n
Будет распределять минимальные фрукты (l) в первых l полях и заполнять остальные оставшимися фруктами на каждой итерации, в то время как в начале каждой итерации будет снова вычисляться минимальный тип фруктов.
Комментарии:
1. звучит неплохо. Что вы придумали до сих пор?
2. Я добавлю то, что я сделал до сих пор в вопросе, мой плохой.
Ответ №1:
Вы можете использовать Object.values()
, array#reduce
и array#forEach
для преобразования вашего объекта.
const boxOfFruits = { apples: [ { name: "Kashmiri", }, { name: "Washington", }, { name: "Himalayan", }, ], oranges: [ { name: "Nagpur", }, { name: "Clementine", }, ], mangoes: [ { name: "Totapuri", }, { name: "Alphonso", }, { name: "Langda", }, ], },
result = Object.values(boxOfFruits).reduce((r, arr) => {
arr.forEach((o,i) => {
const key = `box_${i 1}`;
r[key] ??= r[key] || [];
r[key].push(o)
});
return r;
},{});
console.log(result);
Комментарии:
1. Если я добавлю еще один фрукт в apple, приведенный выше код не будет работать, он создаст поле 3 с двумя фруктами и поле 4 с 1. В то время как в поле 3 должно быть 3 фрукта, что соответствует требованиям для каждого поля
Ответ №2:
Самым простым способом было бы использовать lodash.js zip()
функция:
const boxes = _.zip( Object.values(boxOfFruits) );
Обратите внимание, что _.zip()
это даст вам неопределенные значения, когда исходные массивы имеют разную длину, поэтому вам нужно / нужно их отфильтровать:
const boxes == _.zip( Object.values(boxOfFruits) )
.map(
box => box.filter(
x => x !== undefined
)
);
Но это не приведет к равномерному распределению плодов. Для этого не должно быть намного сложнее, чем это:
function distribute(boxOfFruits, n) {
const boxes = [];
const fruits = Object.keys(boxOfFruits);
for ( const fruit of fruits ) {
let i = 0;
const items = boxOfFruits[fruit];
for (const item of items) {
boxes[i] = !boxes[i] ?? [];
boxes[i] = boxes[i].push(item);
i;
i = i < n ? i : 0 ;
}
}
return boxes;
}
Комментарии:
1. те же части в вашем ответе не работали для меня, обновили и поделились моим собственным ответом. Проверьте
Ответ №3:
Модифицированная версия ответа @Nicholas Carey сработала для меня:
function distribute(boxOfFruits, n) {
let boxes = [];
let totalFruits = Object.values(boxOfFruits)
.reduce((content, current) => content current.length, 0);
let maxBoxes = Math.ceil(totalFruits / 4);
Object.values(boxOfFruits).forEach((fruits) => {
let i = 0;
fruits.forEach((fruit) => {
boxes[i] ??= boxes[i] || [];
boxes[i].push(fruit);
i;
i = i < (n 1) ? i : 0;
});
});
// Extra boxes created, redistribute them to
// starting boxes
let newBoxes = teams.slice(0, maxBoxes);
let pendingBoxes = teams.slice(maxBoxes);
let pendingFruits = pendingBoxes.flat();
let distributedBoxes = newBoxes.map((eachBox) => {
let required = n - eachBox.length;
if (required > 0) {
eachBox.push(...pendingFruits.splice(0, required));
}
return eachBox;
});
return distributedBoxes;
}
Код практически такой же, как у Николаса, примите следующие изменения:
- Непосредственно извлекал значения и повторял их
- не удалось создать пустой массив, этот способ работает
- и проверьте максимальный размер поля с помощью n 1 вместо n