Добавьте два массива целых чисел в массив массивов, чтобы создать пары координат

#javascript #arrays

#javascript #массивы

Вопрос:

У меня есть два массива, один с координатами x и один с координатами y. Мне нужно создать новый массив массивов, которые группируют координаты.

 yCord = [30, 29, 31, 32];
xCord = [0, 1, 2 ,3];
  

Вот что у меня было.

 var cordPairs = {};
xCord.forEach((key, i) => cordPairs[key] = yCord[i]);
  

Но это связывает значения в объекте, мне нужен массив сейчас.

 {0: 30, 1: 29, 2: 31, 3: 32}
  

Желаемый результат:

 cordPairs = [[0, 30], [1, 29], [2, 31], [3, 32]]
  

Комментарии:

1. если желаемый результат cordPairs = [...] зачем вы создаете graphData = {} ?

2. cordPairs = xCord.map((x, i) => [x, yCord[i]])

Ответ №1:

Вам нужны данные в array формате, так что это должно сработать:

 const yCord = [30, 29, 31, 32];
const xCord = [0, 1, 2 ,3];
const coords = xCord.map((el, index)=> [el, yCord[index]]);
console.log(coords);  

Ответ №2:

Вы могли бы взять значения x и y из массива и транспонировать этот массив.

 const
    transpose = (r, a) => a.map((v, i) => [...(r[i] || []), v]),
    yCord = [30, 29, 31, 32],
    xCord = [0, 1, 2 ,3],
    result = [xCord, yCord].reduce(transpose, []);

console.log(result);  
 .as-console-wrapper { max-height: 100% !important; top: 0; }  

Комментарии:

1. Очень классный подход. Я немного запнулся на названии transpose , поскольку такой метод обычно переворачивает матрицу. Но «транспонировать» также имеет второе значение «изменить контекст», которое применимо здесь.

2. @AlexPakka, у тебя есть для этого название получше?

3. @NinaSholz слишком поздно, теперь это застряло у меня в голове. Это точно и работает, я бы оставил это. Все сворачивание / редукция, безусловно, zip() хорошо известная концепция FP и reactive. Но редуктор… хорошо, он переносит элементы из одного массива в другой, ничего особенного. Кстати, у вас есть несколько классных ответов. Сегодня я узнал кое-что новое, спасибо.

Ответ №3:

Другие ответы великолепны, но…

На самом деле это может быть ситуация, когда вместо создания метода, который может выполнять процесс, вы на самом деле захотите создать новую функцию-конструктор, которая вернет объект с врожденной способностью выполнять итерации так, как вы хотите.

 function CoordinateArray(x, y) {
  if (y.length != x.length) return Error("CoordinateArray: Incorrect Array Bounds");
  let i = 0;
  return {
    y,
    x,
    [Symbol.iterator]: function*() {
      while (i < this.y.length) {
        yield [this.x[i], this.y[i]];
        i  ;
      }
    }
  }
}
  

Пример функционирующего кода:

 let yCord = [30, 29, 31, 32],
  xCord = [0, 1, 2, 3];

function CoordinateArray(x, y) {
  if (y.length != x.length) return Error("CoordinateArray: Incorrect Array Bounds");
  let i = 0;
  return {
    x,
    y,
    length: x.length,  
    [Symbol.iterator]: function*() {
      while (i < y.length) {
        yield [this.x[i], this.y[i]];
        i  ;
      }
    }
  };
}

let coords = new CoordinateArray(xCord, yCord);

console.log([...coords]);  

Почему вы сделали бы это таким образом?

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

Создание конструктора для этой цели позволяет создавать код, который подходит для более высоких clarity и concision .

Это также обеспечивает больший внутренний контроль над тем, как вы кодируете.


Что я имею в виду под этим?

Создание метода / функции, которая просто выполняет итерацию по двум массивам один раз и возвращает объединенный массив координат, — это хорошо, но давайте предположим, что где-то в дальнейшем вам просто нужно скорректировать все x значения. С обычной функцией вам нужно было бы либо написать условия, либо выполнить функцию, а затем выполнить дополнительную работу, чтобы получить желаемые результаты. A.e.:

 getCoordinateArray(xCord, yCord) //perform a lot of work
  .map(([x,y]) => [x*2,y]);      //perform more work
  

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

 let coords = CoordinateArray(xCord, yCord); //initial work
coords.x = coords.x.map(i=>i*2); //minimal work
  

Это может быть не совсем понятно, но, делая это способом конструктора, вы настраиваете объект как можно минимальнее, сохраняя при этом функциональную парадигму. Вы не беспокоитесь об итоговых результатах, вы только корректируете то, что вам нужно, и результат будет таким, как ожидалось. Кроме того, совершенно ясно, что вы настраиваете во втором примере coords.x , тогда как в первом это скорее беспорядок.

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

  function CoordinateArray(x, y) {
  return {
  ...
   //new method
    move: function(s, c = s.split("")[0]) { this[c] = this[c].map(new Function(c,"return"   s)) },
   ...
  }
}
  

И вместо этого приведенное выше станет этим:

 let coords = new CoordinateArray(xCord, yCord); // initial work
coords.move("x*2"); // minimal, clear, work.
  

 let yCord = [30, 29, 31, 32],
  xCord = [0, 1, 2, 3];

function CoordinateArray(x, y) {
  if (y.length != x.length) return Error("CoordinateArray: Incorrect Array Bounds");
  let i = 0;
  return {
    x,
    y,
    move: function(s, [c,] = s.split("")) { this[c] = this[c].map(new Function(c,`return ${s};`)) },
    length: x.length,  
    [Symbol.iterator]: function*() {
      while (i < y.length) {
        yield [this.x[i], this.y[i]];
        i  ;
      }
    }
  };
}

let coords = new CoordinateArray(xCord, yCord);
coords.move("x*2");
console.log([...coords]);  

Думаю, любой скажет, что это намного проще для чтения, но, что более важно, при такой удобочитаемости это ничего вам не стоит. Даже при том, что нет присваивания coords.x , это не изменяет ваши данные. Обычно при выполнении операций вы увидите такие вещи, как x = x.map(); на каждом шаге, которые демонстрируют неизменяемость, но это избыточно и запутывает, когда в этом нет необходимости.


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

Все это, как уже было сказано…

Ваш вариант использования определит наилучший вариант!

Опять же, другие ответы совершенно верны (на самом деле, нескольким другим людям, которые ответили, я намеренно следую, потому что они очень осведомлены и вдохновляют) — я предлагаю этот ответ только для того, чтобы дать больше понимания работы с такими вещами, как системы координат. Я написал много приложений, компонентов и т.д., Которые их использовали, и я потратил много времени на то, чтобы сделать их понятными и эффективными как для себя, так и для других!

Надеюсь, это помогло! Удачного кодирования!

Комментарии:

1. Спасибо за подробный ответ, мне нравится этот подход.

Ответ №4:

Повторите индекс двух массивов, упакуйте пары в массив javascript и pus, чтобы создать из них структуру:

 yCord = [30, 29, 31, 32];
xCord = [0, 1, 2 ,3];
var cordPairs = [];

for(var i = 0; i < xCord.length; i  )
{
  cordPairs.push([xCord[i], yCord[i]]);
}

  

Ответ №5:

Короче говоря, вы хотите сжать эти массивы. С библиотеками, подобными Lodash, это так же просто, как

 cordPairs = _.zip(xCord, yCord);