วิธีการสร้างอาร์เรย์จากอาร์เรย์ [ปิด]


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

คำตอบ:


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}, () => [])ค่าสะสมเริ่มต้น
เบอร์เกน

3
@NinaScholz ไม่ฉันหมายถึงคุณกำลังตรวจสอบว่าr[i]มีอยู่ในการวนซ้ำทุกครั้งหรือไม่ในขณะที่คุณสามารถสร้างอาร์เรย์ผลลัพธ์ที่จำเป็นนอกการreduceโทรได้
Bergi

1
@Klaycon ไม่การเข้าถึงอาร์เรย์ของขอบเขตอาร์เรย์นั้นช้ามากดังนั้น "ตรวจสอบว่ามีอยู่แล้ว" ใช้งานไม่ได้ ความคิดเห็นของฉันไม่ได้หมายถึงการกังวลเกี่ยวกับประสิทธิภาพ แต่ต้องการรหัสที่สะอาดและคาดเดาได้ (ถูกต้อง) ฉันก่อนเขียน "ค่อนข้างน่าเกลียดและช้า" ก่อนที่จะตระหนักว่าคำแนะนำของฉันที่ทำให้การจัดการกับกรณีที่ว่างเปล่าชัดเจนไม่ได้เป็นความงามที่แท้จริงอย่างใดอย่างหนึ่ง
Bergi

14

คุณสามารถใช้วน.map()ซ้ำข้อมูลของคุณและใช้Array 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 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
สิ่งนี้สามารถทำให้เป็นเรื่องทั่วไปได้โดยใช้ไวยากรณ์พารามิเตอร์ที่เหลือถึง([year, ...values]) => [year, values[n]]
JollyJoker

@JollyJoker - คุณควรโพสต์คำตอบนี้เป็นคำตอบทั่วไปที่ดีและกระชับ
Filip Milovanović

@ 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
เป็นไปได้ที่จะสร้างอาร์เรย์แบบไดนามิกโดยไม่ทราบล่วงหน้าว่ามีกี่รายการในอาร์เรย์ดั้งเดิม ลองดูที่คำตอบที่แก้ไขของฉัน :)
อิสมาเอลอาภัพ

4

ก่อนอื่นคุณต้องมีอาร์เรย์ในตอนแรก คุณสามารถmapอาร์เรย์นี้สองอาร์เรย์ที่แตกต่างกันโดยใช้destructuringเพื่อรับแต่ละค่าจาก subarrays ในทางรัดกุม:

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

คุณสามารถใช้ฟังก์ชั่นลดดังต่อไปนี้ซึ่งจะวนซ้ำเพียงครั้งเดียว:

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

สำหรับวิธีแก้ปัญหาทั่วไปฉันคิดว่าการสร้างอาเรย์ของดัชนีสำหรับคอลัมน์ค่าช่วยให้คุณสามารถทำแผนที่ข้อมูลเต็มรูปแบบกับอาร์เรย์ที่คุณต้องการได้อย่างง่ายดาย

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

ให้ดัชนีของคุณเรียงกันลบหนึ่งคอลัมน์นั่นคือปีและ

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

ให้อาร์เรย์ที่คุณต้องการสำหรับคอลัมน์ค่า nth ดังนั้น:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.