Cách tạo mảng từ mảng [đã đóng]


33

Tôi là người mới bắt đầu sử dụng JavaScript và tôi đang thử tạo hai mảng khác nhau với các giá trị từ một mảng chính.

Mảng chính của tôi trông như:

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 ]

Và tôi cần tạo hai mảng, đầu tiên trông giống như:

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]

(giá trị thứ nhất và thứ hai)

và thứ hai như:

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]

(giá trị thứ nhất và thứ ba)

Tôi đang thử mối nối, bộ lọc, vv nhưng tôi không biết làm thế nào để bắt đầu.

Không cần thiết phải viết cho tôi một giải pháp chính xác, mà chỉ cần các bước để làm điều đó.


Cảm ơn bạn rất nhiều vì những câu trả lời tuyệt vời. Họ làm việc tuyệt vời. Tôi có thể có một câu hỏi cho tương lai. Nó có thể được thực hiện để nó không cố định vào hai trường không? Nhưng thậm chí ba, bốn, v.v?
Dominik Lev

3
Vấn đề thực sự bạn đang cố gắng giải quyết ở đây là gì? Có vẻ như sử dụng một mảng các đối tượng là lựa chọn tốt hơn.
BlueRaja - Daniel Pflughoeft

Gợi ý: thay vì có các năm liên tiếp rõ ràng trong mảng của bạn, bạn có thể có năm ẩn từ một điểm bắt đầu nhất định. Sau đó, bạn chỉ cần một điểm bắt đầu vô hướng và năm cho bất kỳ phần tử nào được biết dựa trên chỉ số mảng của nó. (Chỉ hoạt động nếu năm của bạn luôn luôn tiếp giáp và trong thứ tự tăng dần như ví dụ này Nhưng liệu độc đáo đơn giản hóa từ một loạt các cặp để chỉ một mảng các số nguyên thủy..)
Peter Cordes

Câu trả lời:


29

Bạn có thể thực hiện một cách tiếp cận động và nhận tất cả các mục của mảng sau giá trị khóa cho mỗi mảng mới.

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; }


Cảm ơn bạn rất nhiều cho một câu trả lời tuyệt vời. Tôi có thể có một câu hỏi cho tương lai? Có thể làm cho nó cố định không chỉ trên 2 mảng mà còn trên nhiều hơn?
Dominik Lev

1
bạn có thể thay thế [first, second]bằng arrayvà bạn nhận được các mảng với tất cả các cột dữ liệu dưới dạng mảng.
Nina Scholz

2
Thay vì điều đó khá chậm, r[i] = r[i] || []bạn chỉ nên sử dụng Array.from({length: (data[0]?.length ?? 1) - 1}, () => [])cho giá trị tích lũy ban đầu
Bergi

3
@NinaScholz Không, ý tôi là bạn đang kiểm tra xem r[i]có tồn tại trong mỗi lần lặp không, trong khi bạn chỉ cần tạo các mảng kết quả cần thiết bên ngoài reducecuộc gọi.
Bergi

1
@Klaycon Không, truy cập mảng ngoài giới hạn mảng rất chậm, vì vậy "kiểm tra xem đã tồn tại chưa" hoạt động tốt. Nhận xét của tôi không có nghĩa là lo lắng về hiệu suất, nhưng thích mã sạch và có thể dự đoán (chính xác). Lần đầu tiên tôi đã viết "khá xấu xí và chậm chạp" trước khi nhận ra rằng đề nghị của tôi khiến việc xử lý vụ việc trống rỗng rõ ràng cũng không phải là một vẻ đẹp thực sự.
Bergi

14

Bạn có thể sử dụng .map()để lặp lại dữ liệu của mình và sử dụng một số Cấu trúc mảng để có được đầu ra mong muốn:

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; }


Cảm ơn bạn rất nhiều cho một câu trả lời tuyệt vời. Tôi có thể có một câu hỏi cho tương lai? Có thể làm cho nó cố định không chỉ trên 2 mảng mà còn trên nhiều hơn?
Dominik Lev

1
@DominikLev Trong trường hợp đó, bạn có thể sử dụng câu trả lời được đăng bởi Nina. Nó là một trong những tốt.
Mohammad Usman

1
Điều này có thể được khái quát bằng cách sử dụng cú pháp tham số phần còn lại để([year, ...values]) => [year, values[n]]
JollyJoker

@JollyJoker - bạn nên đăng nó như một câu trả lời, đó là một giải pháp tổng quát thực sự tốt đẹp và súc tích
Filip Milovanović

@ FilipMilovanović Tôi đã thực hiện stackoverflow.com/a/60166014/7126740
JollyJoker

6

Bạn có thể sử dụng Array.prototype.forEachđể lặp lại các mục của mảng ban đầu, sau đó tạo các mục mới và đẩy chúng vào các mảng mới:

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);

Đầu ra:

nhập mô tả hình ảnh ở đây


Tạo các mảng của chúng tôi một cách linh hoạt để giải pháp hoạt động cho dù các mảng ban đầu có bao nhiêu mục:

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);

Đầu ra: nhập mô tả hình ảnh ở đây


Cảm ơn bạn rất nhiều cho một câu trả lời tuyệt vời. Tôi có thể có một câu hỏi cho tương lai? Có thể làm cho nó cố định không chỉ trên 2 mảng mà còn trên nhiều hơn?
Dominik Lev

1
Có thể tạo các mảng một cách linh hoạt mà không cần biết trước có bao nhiêu mục mà các mảng ban đầu sẽ có. Hãy xem câu trả lời đã được chỉnh sửa của tôi :)
Ismael Padilla

4

Trước hết, bạn có một mảng các mảng trong đầu. Bạn có thể mapmảng này thành hai mảng khác nhau bằng cách sử dụng destructuringđể nhận từng giá trị từ các tập hợp con một cách ngắn gọn:

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

Lặp lại qua mảng chính và trả về một mảng mới bằng cách sử dụng các giá trị chỉ mục cố định để truy cập các giá trị mảng con của bạn.

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

Bạn có thể sử dụng hàm giảm như sau chỉ lặp lại một lần:

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; }


Tại sao CSS trong câu trả lời này?
Joshua Fox

1
@JoshuaFox chỉ để mở rộng chiều cao của giao diện điều khiển.
Ele

3

Bạn đi đây

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

Tôi đã sử dụng bản đồ cho vòng lặp, hai mảng để đẩy các giá trị cần thiết.

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

giải pháp khác :

 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 ]];

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


1

Đối với giải pháp chung, tôi nghĩ rằng việc xây dựng một mảng các chỉ mục cho các cột giá trị cung cấp cho bạn một cách đơn giản để ánh xạ dữ liệu đầy đủ đến các mảng bạn muốn.

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

cung cấp cho bạn một loạt các chỉ số, trừ đi một cột là năm và

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

cung cấp cho bạn mảng bạn muốn cho cột giá trị thứ n. Vì thế:

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

Một giải pháp khác cho mảng đầu vào có độ dài chung.

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

Sử dụng giải pháp này để thực hiện bất kỳ kết hợp chung nào từ mảng đa chiều hiện có. Bạn phải vượt qua chỉ mục của các mục để chọn một cách rõ ràng và đó là những gì làm cho nó chung chung.

    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));

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.