Diziden diziler nasıl oluşturulur [kapalı]


33

Ben bir JavaScript acemi ve bir ana dizi değerleri ile iki farklı diziler yapmaya çalışıyorum.

Ana dizim şöyle:

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 ]

Ve ilk olarak şu şekilde görünen iki dizi oluşturmam gerekiyor:

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]

(birinci ve ikinci değer)

ve ikincisi şöyle:

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]

(birinci ve üçüncü değer)

Birleştirme, filtre vb. Deniyorum ama nasıl başlayacağımı bilmiyorum.

Bana kesin bir çözüm yazmak gerekli değil, sadece nasıl yapılacağına dair adımlar.


Harika cevaplar için çok teşekkür ederim. Harika çalışıyorlar. Gelecek için bir sorum olabilir. İki alana sabitlenmeyecek şekilde yapılabilir mi? Ama üç, dört vb.
Dominik Lev

3
Burada çözmeye çalıştığınız asıl sorun nedir? Bir nesne dizisini kullanmak daha iyi bir seçenek gibi görünüyor.
BlueRaja - Danny Pflughoeft

Öneri: Dizinizde birbirini takip eden yılların yerine, yılın belirli bir başlangıç ​​noktasından örtük olmasını sağlayabilirsiniz. O zaman sadece bir skaler başlangıç ​​noktasına ihtiyacınız vardır ve herhangi bir elemanın yılı dizi dizinine göre bilinir. (Sadece yıllarınız her zaman bitişik ve bu örnekte olduğu gibi yükseliyorsa çalışır. Ancak bir çift çiftten sadece bir dizi ilkel sayıya kadar basitleştirir.)
Peter Cordes

Yanıtlar:


29

Dinamik bir yaklaşım izleyebilir ve her yeni dizi için anahtar değerinden sonra dizinin tüm öğelerini alabilirsiniz.

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


Harika bir cevap için çok teşekkür ederim. Gelecek için bir soru sorabilir miyim? Sadece 2 diziye değil, daha fazlasına da sabitlenebiliyor mu?
Dominik Lev

1
[first, second]ile değiştirebilir arrayve diziler olarak verilerin tüm sütunlarını içeren diziler alırsınız.
Nina Scholz

2
Bu oldukça yavaş yerine, r[i] = r[i] || []sadece Array.from({length: (data[0]?.length ?? 1) - 1}, () => [])ilk akümülatör değeri için kullanmalısınız
Bergi

3
@NinaScholz Hayır, r[i]her döngü yinelemesinde var olup olmadığını kontrol ettiğiniz anlamına gelirken, reduceçağrı dışında gerekli sonuç dizilerini oluşturabilirsiniz .
Bergi

1
@Klaycon Hayır, dizi sınırları dışından dizi erişimleri süper yavaş olduğundan, "zaten var olup olmadığını kontrol et" iyi çalışmaz. Yorumum performans hakkında endişelenmek değil, temiz ve öngörülebilir (doğru) kodu tercih etmekti. Boş dava ile başa çıkma önermemin gerçek bir güzellik olmadığını fark etmeden önce "oldukça çirkin ve yavaş" yazdım.
Bergi

14

Sen kullanabilirsiniz .map()verilerinize tekrarlatacak ve bazı kullanmak Dizi strüktür istenilen çıktıyı almak için:

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


Harika bir cevap için çok teşekkür ederim. Gelecek için bir soru sorabilir miyim? Sadece 2 diziye değil, daha fazlasına da sabitlenebiliyor mu?
Dominik Lev

1
@DominikLev Bu durumda Nina tarafından gönderilen yanıtı kullanabilirsiniz. İyi bir şey.
Mohammad Usman

1
Bu kullanılarak genelleştirilmiş edilebilir rest parametresi sözdizimini için([year, ...values]) => [year, values[n]]
JollyJoker

@JollyJoker - Bunu bir cevap olarak göndermelisiniz, bu gerçekten güzel ve özlü bir genelleştirilmiş çözüm
Filip Milovanović

@ FilipMilovanović Zaten yaptım stackoverflow.com/a/60166014/7126740
JollyJoker

6

Array.prototype.forEachOrijinal dizinin öğeleri üzerinde yineleme yapabilir , ardından yeni öğeleri oluşturabilir ve bunları yeni dizilere itebilirsiniz:

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

Çıktı:

resim açıklamasını buraya girin


Dizilerimizi dinamik olarak üretmek, böylece orijinal dizilerin kaç öğesi olursa olsun çözüm çalışır:

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

Çıktı: resim açıklamasını buraya girin


Harika bir cevap için çok teşekkür ederim. Gelecek için bir soru sorabilir miyim? Sadece 2 diziye değil, daha fazlasına da sabitlenebiliyor mu?
Dominik Lev

1
Orijinal dizilerin kaç öğeye sahip olacağını önceden bilmeden dizileri dinamik olarak oluşturmak mümkündür. Düzenlediğim yanıta bir göz atın :)
Ismael Padilla

4

Her şeyden önce, başlangıçta bir dizi diziniz var. mapBu diziyi destructuring, alt dizilerden her bir değeri özlü bir şekilde almak için kullanarak iki farklı diziye yapabilirsiniz :

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

Ana dizi arasında dolaşın ve alt dizininizin değerlerine erişmek için sabit dizin değerlerini kullanarak yeni bir dizi döndürü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

Azaltma işlevini, yalnızca bir kez yinelenen aşağıdaki gibi kullanabilirsiniz:

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


Bu cevaptaki neden CSS?
Joshua Fox

1
@JoshuaFox sadece konsolun yüksekliğini artırmak için.
Ele

3

Hadi bakalım

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

Döngü için harita kullandım, gerekli değerleri itmek için iki dizi.

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

başka bir çözüm :

 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]]]). azaltın ((a, b) => a.concat (b), [])


1

Genel çözüm için, ben değer sütunları için bir dizin dizini oluşturmak tam veri istediğiniz diziler eşleme için basit bir yol sağlar düşünüyorum.

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

size yıl olan bir sütun eksi olarak bir dizi indeks verir ve

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

n'inci değer sütunu için istediğiniz diziyi verir. Yani:

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

Genel uzunluktaki giriş dizileri için başka bir çözüm.

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

Mevcut çok boyutlu diziden herhangi bir genel kombinasyon oluşturmak için bu çözümü kullanın. Açık bir şekilde seçim yapmak için öğe dizinini geçmelisiniz ve bu onu genel yapan da budur.

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.