JavaScript'te dizi dizilerini ayrıştırma

Herhangi bir dizi dizisi içerebilen bir diziden bir değer döndürecek bir işleve ihtiyacım var. GetValueFromArray (array, [2, 4]) gibi çağrılmalıdır - bu örnek geçirilen dizinin 2d dizisinin 4. elemanını döndürmelidir.

İşte kodum:

function getValueFromArray(arr, indexes){

var val,
    currentIndex = indexes[0];

    if(!arr[currentIndex] || arr[currentIndex] === '') return value = '';

    indexes.splice(0, 1);

    if(arr[currentIndex].length) 
        getValueFromArray(arr[currentIndex], indexes);
    else {
        val = arr[currentIndex];
        return val;
    }
 }


      var y = getValueFromArray([[1,2,3,4], [1,2,3,4]], [0, 2]);//should return 3

      var x = getValueFromArray([[1,2,3,4], [1,2,3,4], [5,6,7,8]], [2, 3]);//should return 8

      var z = getValueFromArray(
                           [
                               [[1,2,3,4], [1,2,3,4], [1,2,3,4]],
                               [[1,2,3,4], [1,2,3,4]]
                           ], 
                           [0, 1, 2]
                          );//should return 3

Böyle bir çağrı 3 döndürmeli ve eğer fonksiyonun hata ayıklamasını yaparsam, aslında doğru değeri döndürür, fakat bir değişkene atadığımda tanımsız döndürür. Sanırım özyinelemeden dolayı, değişken ilk işlev çağrısı sırasında tanımsız olan değeri alır. Bu nasıl düzeltilebilir?

Teşekkür ederim!

0
'Dizinlerin' uzunluğu her zaman tam olarak 2 olacak mı?
katma yazar radiaph, kaynak
if (arr [currentIndex] .length) 'den sonra bir dönüş ' i kaçırdınız, bu yüzden neden bu kadar karmaşık bir çözüme ulaşmadınız? dizinin 2'den fazla boyutu olabilir mi?
katma yazar Stefan Baiu, kaynak
Sadece bir not: indexes.splice (0, 1) :) yerine indexes.shift() kullanılabilir.
katma yazar Stefan Baiu, kaynak
Evet, daha karmaşık dizileri de ayrıştırabilecek bir çözüme ihtiyacım vardı. Tahminin için teşekkürler, şimdi işe yarıyor.
katma yazar Caminante, kaynak

8 cevap

Bunu çok fazla düşünüyorsun:

function getValueFromArray(arr, indexes){
    return arr[indexes[0]][indexes[1]];
}

1 ila 3 boyutlu dizi için EDIT:

function getValueFromArray(arr, indexes){
    if (indexes.length == 1) {
        return arr[indexes[0]];
    } else if (indexes.length == 2) {
        return arr[indexes[0][indexes[1]];
    } else if (indexes.length == 3) {
        return arr[indexes[0][indexes[1][indexes[2]];
    } else {
     //4 dimensional arrays???
    }
}

3 boyutlu diziden daha fazlasına sahip miydiniz?

indexleri [i] eklemenin bir yolunu bulmak en iyisi olur, ancak şu anda bir yol düşünemiyorum ve bunun mümkün olduğunu sanmıyorum.

1
katma
@Caminante neden 3 boyuttan daha fazlasına sahiptiniz? Dizilerde bu kadar büyük gidiyorsanız, belki bir veritabanına ihtiyacınız var gibi geliyor.
katma yazar Code Whisperer, kaynak
@Caminante yaptığım düzenleme 3 boyutluya kadar işleyebilir, 4, 5 vb. Kodlar ekleyebilirsiniz. Özyineleme kadar uyarlanabilir/genel değildir, ancak bir noktaya kadar anlaşılması ve daha az kodlanması daha kolaydır.
katma yazar Code Whisperer, kaynak
@Caminante: belki sorunuzu güncellemeli ve 3 boyutlu bir dizi (+ istenen sonucu) ile bir örnek sunmalısınız, bu, sorunuza rastlayan birçok insan için işleri açıklığa kavuşturacaktır.
katma yazar Stefan Baiu, kaynak
Fakat indeks miktarı farklı olabilir ve eğer içimde daha fazla dizi varsa bu çözüm işe yaramaz.
katma yazar Caminante, kaynak
@Stefan Baiu Öneriniz için teşekkürler, asıl soruya daha fazla örnek ekledim. @ Code Whisperer Farklı diziler için kullanılacak, çoğunlukla 2 boyutlu, haklısın. Ancak biraz daha karmaşık dizilerle de yüzleşmeye hazır olmalı :)
katma yazar Caminante, kaynak

Özyinelemeli sonuçlarınızı geri göndermiyorsunuz.

if(arr[currentIndex].length) 
    getValueFromArray(arr[currentIndex], indexes);

Olmalı:

if(arr[currentIndex].length) 
    return getValueFromArray(arr[currentIndex], indexes);
1
katma
function getValueFromArray(arr, indexes) {
   //exit if arr is not an array
   //exit if arr is empty
   //exit if indexes is not an array
   //exit if indexes is empty
    if (!Array.isArray(arr) || !arr.length || !Array.isArray(indexes) || !indexes.length) {
        return;//may throw exception or return other value
    }
    var currentIndex = indexes.shift();
   //exit if index is not in arr
   //exit if index is negative
    if (arr.length <= currentIndex || currentIndex < 0) {
        return;//may throw exception or return other value
    }
    return Array.isArray(arr[currentIndex]) ? getValueFromArray(arr[currentIndex], indexes) : arr[currentIndex];
}
0
katma

Tahminin doğru. Özyinelemeli çağrı ne olursa olsun, return 'i unuttum:

if(arr[currentIndex].length) 
    getValueFromArray(arr[currentIndex], indexes);//<---- here

Olduğu söyleniyor, kolayca daha kısa sürede yapabileceğinizi kabul etmek zorundayım (ancak bu sonuçta indexleri imha edecektir):

function getValueFromArray(arr, indexes){
  while(indexes.length) arr=arr[indexes.shift()]
  return arr
}
0
katma
Düzenlendi (çok fazla kod yazdığınızı kabul etmek zorunda kaldı): Sürümümü beğenmişsinizdir :)
katma yazar Touffy, kaynak
Versiyonunu beğendim! Hala kodumu daha kısa hale getirmeyi öğreniyorum, yardımın için teşekkürler :)
katma yazar Caminante, kaynak

Daha önce bir geri dönüş eklemeniz gerektiğini düşünüyorum getValueFromArray (arr [currentIndex], indexes);
Her bir tekrarlanan çağrı geri döndüğünde özyinelemeli yöntem çağrısı yığınını tekrarlamak için son hesaplanan değeri yapmak.

0
katma

kodunuzda bir şeyi kaçırdınız (koşuldan sonra sonucu döndürerek) verilen kodu aşağıda deneyin: -

function getValueFromArray(arr, indexes){

    var val,
        currentIndex = indexes[0];

        if(!arr[currentIndex] || arr[currentIndex] === '') return value = '';

        indexes.splice(0, 1);

        if(arr[currentIndex].length) 
           return getValueFromArray(arr[currentIndex], indexes);
        else {
            val = arr[currentIndex];
            return val;
        }
     }
    var y = getValueFromArray([[1,2,3,4], [1,2,3,4]], [0, 2]);
    console.log(y)

çalıştırın ve bakın, şimdi sonucu değişkene gösteriyor.

0
katma

Sorunumu daha basit bir çözüm sağladığını düşündüğüm için kodumu da gönderirim.
Dahil hiçbir özyineleme yoktur, bu yüzden teoride biraz daha hızlı çalışması gerekir.

var arr = [
  [
    [
      [12, 5, 6],
      [ 6, 7, 8],
      [11, 0, 9]
    ],
    [
      [-1, 1, 8],
      [ 4, 5, 6]
    ]
  ],
  [
    [
        [7, 8, 9, 10]
    ]
  ]
];

function getValueFromArray(arr, indexes){
    var value = arr, i = 0, len = indexes.length, index = null;

    for (; i < len; i += 1) {
        index = indexes[i];
       //check if the current array contains an {index}-th record
        if ( index in value ) { 
            value = value[index];
        } else {
           //or throw an exception if you want
            return null;
        }
    }

    return value;
 }

getValueFromArray(arr, [0, 1, 1, 2])//6
0
katma

It's because if condition is not returning any value. Try following code

function getValueFromArray(arr, indexes){

var val='',currentIndex = indexes[0];

    if(!arr[currentIndex] || arr[currentIndex] === '') return val;

    indexes.splice(0, 1);

    if(arr[currentIndex].length) {

      //Because if your function walks this way 
      //it does not meet any 'return' statement
      //till the end and returns nothing.
        return getValueFromArray(arr[currentIndex], indexes);
    }   
    else { 
        val = arr[currentIndex];
        return val;
    }
 }

Sonra konsol günlüğünü değişken

var y = getValueFromArray([[1,2,3,4], [1,2,3,4]], [0, 2]);
console.log(y)
0
katma