JavaScript: создание двухмерного массива объектов на основе условия - PullRequest
0 голосов
/ 19 января 2019

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

Давайте предположим, что в City A есть приюты для животных, и что каждый может содержать 50 животных. Животные прибывают из разных частей штата, но количество животных из одного места никогда не может превышать 50. Вот пример животных, прибывающих.

let animal_shelter_capacity =< 50;

let array 1 = [
  { "region": "NE", quantity: 25 },
  { "region": "NW", quantity: 21 },
  { "region": "SE", quantity: 43 },
  { "region": "SW", quantity: 18 },
  { "region": "Central", quantity: 20} 
]

В этом примере животные из NE (25) и NW (21) пойдут в один приют (всего 46 животных), животные из SE (43) пойдут в другой приют ( 43 животных), а животные из SW (18) и Central (20) пойдут в третий приют (всего 38 животных). Количество животных в одном приюте никогда не может превышать 50.

Итак, мне нужно создать массив, который выглядит следующим образом:

let array2 = [ 
  [ { "region": "NE", quantity: 25 }, { "region": "NW", quantity: 21 }],
  [ { "region": "SE", quantity: 43 } ],
  [ { "region": "SW", quantity: 18 }, { "region": "Central", quantity: 20} ] 
]

Я могу перебрать array1, используя forEach, но когда дело доходит до добавления до достижения определенного значения, а затем создания нового массива массивов, я немного озадачен тем, как перейти к сделай это.

Вот что у меня есть:

let array2 = [] //instantiate array

array1.forEach(function(element, index, array)
{
    let sum = 0;
    let capacity = 50;

    for (let j = 0; j < array1.length; j++)
    {
        sum += array1[j].quantity;
        if (sum >= capacity)
        {
            //create the new array consisting of the regions, push it into the larger array2
        }
    }
})

Я не уверен, как продолжать это делать. Я знаю, что мне нужно сделать следующее:

1. find a way to cut off the addition sequence once the quantity reaches 50
2. reset the sequence 
3. form the new arrays and push them into a larger array

Может ли кто-нибудь дать совет, как поступить?

Ответы [ 3 ]

0 голосов
/ 19 января 2019

Вы можете подойти к этому с помощью lower () , используя пользовательский объект в качестве начального accumulator. Когда сокращение завершится, вам нужно будет сделать дополнительную строку кода, чтобы получить окончательный результат.

const animal_shelter_capacity = 50;

const array1 = [ 
    {"region": "NE", quantity: 25},
    {"region": "NW", quantity: 21},
    {"region": "SE", quantity: 43},
    {"region": "SW", quantity: 18},
    {"region": "Central", quantity: 20} 
];

let obj = array1.reduce((res, curr) =>
{
    let test = (curr.quantity + res.c >= animal_shelter_capacity);

    return {
        r: test ? [...res.r, res.a] : res.r,
        c: test ? curr.quantity : res.c + curr.quantity,
        a: test ? [curr] : [...res.a, curr]
    };
},{r:[], c:0, a:[]});

let newArr = [...obj.r, obj.a];
console.log(newArr);

В предыдущем коде накопленный объект имеет следующие ключи:

  • r : Множество укрытий, создаваемых постепенно.
  • c : Счетчик животных текущего приюта (см. Далее).
  • a : текущий приют для животных.

Когда закончится reduce, последнее укрытие (которое находится в собственности a) не будет находиться в массиве укрытий. Итак, мы должны поставить его вручную (это то, что делает дополнительная строка).

0 голосов
/ 19 января 2019

Первое, что я пришёл в голову, это то, что вам нужно сначала отсортировать входные данные. потому что ваши данные (как указано в вопросе) не единственный возможный способ получения данных.

У вас могут быть такие данные, как:

let array1 = [ 
{ "region": "NE", quantity: 25 },
{ "region": "NW", quantity: 21 },
{ "region": "Central", quantity: 20 },
{ "region": "SE", quantity: 43 },
{ "region": "SW", quantity: 18 },
]

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

Итак, вывод. Я думаю, что это сработает:

var make = function( arr ) {
    
        var res = [],
            currentArr = [];

        arr.forEach( v => {

            sum += v.quantity;

            if ( sum <= capacity ) {

                currentArr.push( v );

            } else {

                res.push( currentArr );
                currentArr = [ v ];
                sum = v.quantity;

            }

        });

        res.push( currentArr );

        return res;

    },

    array1 = [

        { "region": "NE", quantity: 25 },
        { "region": "NW", quantity: 21 },
        { "region": "Central", quantity: 20 },
        { "region": "SE", quantity: 43 },
        { "region": "SW", quantity: 18 }

    ],

    sum = 0,
    result,
    capacity = 50;

array1.sort( ( a, b ) => {

    return a.quantity - b.quantity;

});

console.log( array1 );

result = make( array1 );

console.log( result );
0 голосов
/ 19 января 2019

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

const locations = [{
    "region": "NE",
    "quantity": 25
  },
  {
    "region": "NW",
    "quantity": 21
  },
  {
    "region": "SE",
    "quantity": 43
  },
  {
    "region": "SW",
    "quantity": 18
  },
  {
    "region": "Central",
    "quantity": 20
  }
]

const shelterRoster = [];
const capacity = 50;
let count = 0;
for (let location of locations) {
  let shelter = shelterRoster[shelterRoster.length - 1];

  if (!shelter || count + location.quantity > capacity) {
    shelterRoster.push([location]);
    count = 0;
  } else {
    shelter.push(location);
  }

  count += location.quantity
}

console.log(shelterRoster);
...