如何从数组创建数组


33

我是一名JavaScript初学者,我尝试使用一个主数组中的值制作两个不同的数组。

我的主数组如下:

0: Array(3) [ 2011, 127072.7, 51584 ]
1: Array(3) [ 2012, 125920.3, 59974 ]
2: Array(3) [ 2013, 129305.4, 15468 ]
3: Array(3) [ 2014, 135364, 84554 ]
4: Array(3) [ 2015, 136757, 98754 ]
5: Array(3) [ 2016, 155653.5, 155548 ]
6: Array(3) [ 2017, 164130.5, 284848 ]

我需要创建两个数组,首先看起来像:

0: Array(2) [ 2011, 127072.7]
1: Array(2) [ 2012, 125920.3]
2: Array(2) [ 2013, 129305.4]
3: Array(2) [ 2014, 135364]
4: Array(2) [ 2015, 136757]
5: Array(2) [ 2016, 155653.5]
6: Array(2) [ 2017, 164130.5]

(第一个和第二个值)

第二个像:

0: Array(2) [ 2011, 51584]
1: Array(2) [ 2012, 59974]
2: Array(2) [ 2013, 15468]
3: Array(2) [ 2014, 84554]
4: Array(2) [ 2015, 98754]
5: Array(2) [ 2016, 155548]
6: Array(2) [ 2017, 284848]

(第一个和第三个值)

我尝试连接,过滤器等,但是我不知道如何开始。

没必要给我写一个确切的解决方案,而只是一步一步地去做。


非常感谢您的出色回答。他们工作很棒。我可能对未来有一个疑问。可以做到不将其固定在两个字段上吗?但是,甚至三个,四个等等?
Dominik Lev

3
您要在这里解决的实际问题是什么?似乎使用对象数组是更好的选择。
BlueRaja-Danny Pflughoeft

建议:您可以在给定的起始点隐含年份,而不是在数组中连续显示明确的年份。然后,您只需要一个标量起点,并且根据其数组索引就可以知道任何元素的年份。(仅当您的年份总是连续且升序(如本例所示)时才有效。但是可以很好地将其从成对的数组简化为仅原始数的数组。)
Peter Cordes

Answers:


29

您可以采用动态方法,并在每个新数组的键值之后获取数组的所有项目。

var data = [[2011, 127072.7, 51584], [2012, 125920.3, 59974], [2013, 129305.4, 15468], [2014, 135364, 84554], [2015, 136757, 98754], [2016, 155653.5, 155548], [2017, 164130.5, 284848]],
    [first, second] = data.reduce(
        (r, [k, ...a]) => {
            a.forEach((v, i) => r[i].push([k, v]));
            return r;
        },
        Array.from({ length: Array.isArray(data[0]) ? data[0].length - 1 : 0 }, () => [])
    );

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


非常感谢您的出色回答。我可以对未来有疑问吗?是否可以使其不仅固定在2个阵列上,还可以固定在更多阵列上?
Dominik Lev

1
您可以将其替换为[first, second]array并获得将所有数据列都作为数组的数组。
妮娜(Nina Scholz)

2
而不是那么慢,r[i] = r[i] || []您应该只使用Array.from({length: (data[0]?.length ?? 1) - 1}, () => [])初始累加器值
Bergi

3
@NinaScholz不,我的意思是您要检查r[i]每个循环迭代中是否存在,而您可以在reduce调用之外简单地创建必要的结果数组。
Bergi

1
@Klaycon不,超出数组范围的数组访问非常慢,因此“检查是否已存在”效果不佳。我的评论并不是要担心性能,而是希望使用干净且可预测(正确)的代码。我首先写了“相当丑陋且缓慢”的文章,然后才意识到我提出的明确处理空案的建议也不是真正的美。
Bergi

14

您可以.map()用来遍历数据并使用一些数组分解来获得所需的输出:

const data = [
  [ 2011, 127072.7, 51584 ],
  [ 2012, 125920.3, 59974 ],
  [ 2013, 129305.4, 15468 ],
  [ 2014, 135364, 84554 ],
  [ 2015, 136757, 98754 ],
  [ 2016, 155653.5, 155548 ],
  [ 2017, 164130.5, 284848 ]
];

const arr1 = data.map(([year, val]) => ([year, val]));
const arr2 = data.map(([year, _, val]) => ([year, val]));

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


非常感谢您的出色回答。我可以对未来有疑问吗?是否可以使其不仅固定在2个阵列上,还可以固定在更多阵列上?
Dominik Lev

1
@DominikLev在这种情况下,您可以使用Nina发表的答案。这是一个很好的。
Mohammad Usman

1
可以使用rest参数语法将其推广到([year, ...values]) => [year, values[n]]
JollyJoker

@JollyJoker-您应该将其发布为答案,这是一个非常不错且简洁的通用解决方案
FilipMilovanović

@FilipMilovanović我已经做了stackoverflow.com/a/60166014/7126740
JollyJoker

6

您可以Array.prototype.forEach用来遍历原始数组的项目,然后创建新项目并将其推入新数组:

var original = [[ 2011, 127072.7, 51584 ], [ 2012, 125920.3, 59974 ], [ 2013, 129305.4, 15468 ]]

var array1 = []
var array2 = []

original.forEach(item => {
  array1.push([item[0], item[1]]);
  array2.push([item[0], item[2]]);
});

console.log(array1);
console.log(array2);

输出:

在此处输入图片说明


动态生成我们的数组,因此无论原始数组有多少项,该解决方案都可以工作:

var original = [
  [2011, 127072.7, 51584, 1, 2, 3],
  [2012, 125920.3, 59974, 4, 5, 6],
  [2013, 129305.4, 15468, 7, 8, 9]
]

// Array of arrays
var myArray = []

// Fill it with empty arrays
for (var i = 0; i < original[0].length - 1; i++)
  myArray.push([])

// Iterate over original
// For each original, insert the first and i-th element into our array of arrays
original.forEach(item => {
  for (var i = 1; i < item.length; i++) {
    myArray[i - 1].push([item[0], item[i]]);
  }
});

console.log(myArray);

输出: 在此处输入图片说明


非常感谢您的出色回答。我可以对未来有疑问吗?是否可以使其不仅固定在2个阵列上,还可以固定在更多阵列上?
Dominik Lev

1
可以动态生成数组,而无需事先知道原始数组有多少个项目。看一看我编辑过的答案:)
Ismael Padilla

4

首先,开始时会有一个数组数组。您可以map将此数组分为两个不同的数组,用于destructuring以简洁的方式从子数组中获取每个值:

const data = [
  [ 2011, 127072.7, 51584 ],
  [ 2012, 125920.3, 59974 ],
  [ 2013, 129305.4, 15468 ],
  [ 2014, 135364, 84554 ],
  [ 2015, 136757, 98754 ],
  [ 2016, 155653.5, 155548 ],
  [ 2017, 164130.5, 284848 ],
];

const array1 = data.map(([first, second, third]) => [first, second]);
const array2 = data.map(([first, second, third]) => [first, third]);

console.log(JSON.stringify(array1));
console.log(JSON.stringify(array2));


4

循环遍历主数组,并通过使用固定索引值访问您的子数组值来返回新数组。

const multiDimArr = [
  [2011, 127072.7, 51584],
  [2012, 125920.3, 59974],
  [2013, 129305.4, 15468],
  [2014, 135364, 84554],
  [2015, 136757, 98754],
  [2016, 155653.5, 155548],
  [2017, 164130.5, 284848],
]

const arr1= multiDimArr.map(x=>[x[0],x[1]]);
const arr2= multiDimArr.map(x=>[x[0],x[2]]);

console.log(arr1)
console.log(arr2)


3

您可以按如下方式使用reduce函数,该函数仅迭代一次:

let matrix = [[ 2011, 127072.7, 51584 ],[ 2012, 125920.3, 59974 ],[ 2013, 129305.4, 15468 ],[ 2014, 135364, 84554 ],[ 2015, 136757, 98754 ],[ 2016, 155653.5, 155548 ],[ 2017, 164130.5, 284848 ]];

let result = matrix.reduce((a, [year, k, v]) => {
  a.second.push([year, k]);
  a.third.push([year, v]);
  return a;
}, {second: [], third: []});

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


为什么在这个答案中使用CSS?
Joshua Fox

1
@JoshuaFox仅用于扩展控制台的高度。
Ele

3

干得好

let values = [[ 2011, 127072.7, 51584 ],[ 2012, 125920.3, 59974 ],[ 2013, 129305.4, 15468 ],[ 2014, 135364, 84554 ],[ 2015, 136757, 98754 ],[ 2016, 155653.5, 155548 ],[ 2017, 164130.5, 284848 ]];

let chunk1 = values.map(arr1 => {
  return [arr1[0], arr1[1]]
});
let chunk2 = values.map(arr1 => {
  return [arr1[0], arr1[2]]
})

console.log("Chunk 1", chunk1);
console.log("Chunk 2", chunk2);


2

我已经使用map for loop,两个数组来推送所需的值。

let point_table = []
let integer_table = []
const historical_table = [
  [2011, 127072.7, 51584],
  [2012, 125920.3, 59974],
  [2013, 129305.4, 15468],
  [2014, 135364, 84554],
  [2015, 136757, 98754],
  [2016, 155653.5, 155548],
  [2017, 164130.5, 284848]
]
historical_table.map(row => {
  point_table.push([row[0], row[1]])
  integer_table.push([row[0], row[2]])
})
console.log(point_table, integer_table)


1

另一个解决方案:

 const original= [  [ 2011, 127072.7, 51584 ], [ 2012, 125920.3, 59974 ],[ 2013, 129305.4, 15468 ],  [ 2014, 135364, 84554 ],  [ 2015, 136757, 98754 ],  [ 2016, 155653.5, 155548 ],  [ 2017, 164130.5, 284848 ]];

original.map(x => [[[x [0],x [1]],[x [0],x [2]]]).reduce((a,b)=> a.concat(b), [])


1

对于通用解决方案,我认为为value列构建索引数组为您提供了一种将完整数据映射到所需数组的简单方法。

[...data[0].keys()].slice(0,-1)

给您一系列的索引,减去年份的一列,然后

n => data.map(([year, ...values]) => [year, values[n]])

为您提供所需的第n个值列的数组。所以:

var data = [[2011, 127072.7, 51584], [2012, 125920.3, 59974], [2013, 129305.4, 15468], [2014, 135364, 84554], [2015, 136757, 98754], [2016, 155653.5, 155548], [2017, 164130.5, 284848]]

const yearArrays = arr => [...arr[0].keys()].slice(0,-1)
       .map(arr.map(([year, ...values]) => [year, values[n]]))

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


0

通用长度输入数组的另一种解决方案。

const input = [[1,11,111,1111],[2,22,222,2222]];

const result = input.reduce((accumulator, [head, ...tail]) => {
  tail.forEach((item, index) => {
    accumulator[index] = accumulator[index] || [];
    accumulator[index].push([head, item]);
  });
  return accumulator;
}, [])

console.log(result);


0

使用此解决方案可以从现有的多维数组进行任何通用组合。您必须传递要明确选择的项目索引,这就是使其通用的原因。

    const multiDimArr = [
      [2011, 127072.7, 51584],
      [2012, 125920.3, 59974],
      [2013, 129305.4, 15468],
      [2014, 135364, 84554],
      [2015, 136757, 98754],
      [2016, 155653.5, 155548],
      [2017, 164130.5, 284848],
    ]


    function arrayCombo (idxA, idxB){
      return multiDimArr.map(x=>[x[idxA],x[idxB]]);
    }

    console.log(arrayCombo(0, 1));
    console.log(arrayCombo(0, 2));
    console.log(arrayCombo(1, 2));

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.