Javascript - μετατροπή ένθετων πινάκων σε αντικείμενο συστοιχίες

ψήφοι
1

Έχω μια ένθετη συστοιχία με άγνωστα σχήμα. Εδώ είναι ένα παράδειγμα:

[head,val1,val2,val3,
    [head2,val4,val5,
        [head3,val6,val7, 
            [head4, val8],val9]],
    [head5, val10, val11]
]

Οι πίνακες έχουν όλα μήκος 2 ή μεγαλύτερο. Μία συστοιχία μπορεί να περιέχει οποιοδήποτε αριθμό άλλων συστοιχιών το οποίο μπορεί επίσης να περιέχει οποιονδήποτε αριθμό συστοιχιών. Όλες οι τιμές είναι είτε χορδές ή συστοιχίες.

Προσπαθώ να μετατρέψει αυτό σε ένα ενιαίο αντικείμενο με το ακόλουθο σχήμα:

{head: [val1,val2,val3, 
    {head2: [val4,val5, 
        {head3: [val6,val7, 
            {head4: [val8]}, val9]},
    {head5: [val10, val11]}
]}

Βασικά, κάθε συστοιχία πρέπει να μετατραπεί σε ένα αντικείμενο, όπου η πρώτη τιμή είναι το κλειδί και το υπόλοιπο της συστοιχίας είναι η τιμή. Έχω δοκιμάσει τη χρήση reduce, αλλά δεν μπορώ να το πάρει σωστό.

Δημοσιεύθηκε 07/11/2018 στις 23:44
πηγή χρήστη
Σε άλλες γλώσσες...                            


6 απαντήσεις

ψήφοι
4

Σε αυτήν την περίπτωση, δεν ξέρεις πόσο βαθιά είναι ένθετων πινάκων σας, γι 'αυτό είναι μια καλή ιδέα να σχεδιάσει μια αναδρομική συνάρτηση.

Στο βασικό σενάριο των αναδρομικών λειτουργίας σας, η είσοδος δεν είναι ένας πίνακας, έτσι απλά να επιστρέψει την είσοδο.

Σε περίπτωση που η είσοδος είναι ένας πίνακας, δημιουργήστε ένα αντικείμενο JS με ένα μόνο ακίνητο του οποίου το όνομα είναι ίσο με το πρώτο στοιχείο του πίνακα εισόδου, και των οποίων η αξία είναι ίση με το υπόλοιπο της σειράς ... Θα πρέπει να καλέσετε αναδρομικά λειτουργία σας από κάθε ένα από τα υπόλοιπα μέλη του για να πάρει την αξία τους στην προκύπτουσα σειρά.

var a = ["head","val1","val2","val3",
    ["head2","val4","val5",
        ["head3","val6","val7", 
            ["head4", "val8"],"val9"]],
    ["head5", "val10", "val11"]
];

function convert(val) {
  var result;
  if (Array.isArray(val)) {
    var key = val[0];
    var vals = val.slice(1);
    result = {};
    result[key] = [];
    for (var i = 0; i < vals.length; i++) {
      result[key].push(convert(vals[i]));
    }
  } else {
    result = val;
  }
  return result;
}

console.log(convert(a));

Απαντήθηκε 08/11/2018 στις 00:00
πηγή χρήστη

ψήφοι
2

Κάτι σαν αυτό?

function convert(arr) {
  if (arr instanceof Array) {
    const [key, ...values] = arr;
    return { [key]: values.map(convert) };
  } else {
    return arr;
  }
}

const test = ["head","val1","val2","val3",
    ["head2","val4","val5",
        ["head3","val6","val7", 
            ["head4", "val8"],"val9"]],
    ["head5", "val10", "val11"]
];

console.log(convert(test));

Απαντήθηκε 08/11/2018 στις 00:13
πηγή χρήστη

ψήφοι
2

Μόλις το κάνετε αναδρομικά όπως έτσι:

function convert(arr) {
  return {
    [arr[0]]: arr.slice(1).map(item => Array.isArray(item)? convert(item): item)
  }
}

Η συνάρτηση convertεπιστρέφει ένα αντικείμενο containg ένα ζεύγος κλειδιού-τιμής. Το κλειδί είναι arr[0]και η τιμή είναι το υπόλοιπο των στοιχείων στη συστοιχία ( arr.slice(1)) χαρτογράφησαν σε μια νέα συστοιχία τέτοια που convertονομάζεται επί όλων των στοιχείων συστοιχίας μέσα σε αυτό το array.

ES5 Έκδοση:

function convert(arr) {
  var obj = {};
  obj[arr[0]] = arr.slice(1).map(function(item) {
      return item instanceof Array? convert(item): item;
  });
  return obj;
}

Παράδειγμα:

function convert(arr) {
  return {
    [arr[0]]: arr.slice(1).map(item => Array.isArray(item)? convert(item): item)
  }
}

let arr = ["head","val1","val2","val3",
    ["head2","val4","val5",
        ["head3","val6","val7", 
            ["head4", "val8"],"val9"]],
    ["head5", "val10", "val11"]
];

let result = convert(arr);

console.log(result);

Απαντήθηκε 08/11/2018 στις 00:05
πηγή χρήστη

ψήφοι
1

Από τη στιγμή που tagged αυτό με lodashεδώ είναι μια σύντομη λύση με αυτό, καθώς και:

var data = ["head","val1","val2","val3", ["head2","val4","val5", ["head3","val6","val7", ["head4", "val8"],"val9"]], ["head5", "val10", "val11"] ]

const f = (d) => ({[_.head(d)]: _.map(_.tail(d), x => _.isArray(x) ? f(x) : x)})

console.log(f(data))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Πρόκειται για μια αναδρομική λύση η οποία χρησιμοποιεί lodash .head να πάρει το πρώτο στοιχείο της συστοιχίας,.tail να πάρει όλα, αλλά το πρώτο και στη συνέχεια_.mapνα πάει πέρα από κάθε ένα από τα στοιχεία και να επιστρέψει έναν πίνακα.

Απαντήθηκε 08/11/2018 στις 02:34
πηγή χρήστη

ψήφοι
1

Αυτή η αποτελεσματική προσέγγιση αποφεύγει τη χρήση slice()(η οποία θα δημιουργήσει ένα προσωρινό πίνακα μεγέθους Ν-1 που παίρνει έπεσε):

function change(a) {
  let b = [];
  for (let i = 1; i < a.length; i++) {
    let v = a[i];
    b.push(Array.isArray(v) ? change(v) : v);
  }
  return {[a[0]]: b};
}

console.log(change(
  ["head","val1","val2","val3",
    ["head2","val4","val5",
        ["head3","val6","val7", 
            ["head4", "val8"],"val9"]],
    ["head5", "val10", "val11"]
  ]
));

Απαντήθηκε 08/11/2018 στις 01:50
πηγή χρήστη

ψήφοι
1

ES6: Μπορείτε να κάνετε κάτι σαν το παρακάτω

function convertArrayToObject(arr) {
  return Array.isArray(arr) && arr.length ? {
    [arr[0]]: arr.slice(1).map(convertArrayToObject)
  } : arr;
}

Αυτό κώδικας ορίζει μια συνάρτηση convertArrayToObjectπου επιστρέφει το στοιχείο η ίδια και αν δεν είναι μια συστοιχία ή ορίζει το πρώτο στοιχείο ως το κλειδί και καλεί τη συνάρτηση εάν με τα υπόλοιπα στοιχεία ως τιμές αν είναι μια συστοιχία.

Απαντήθηκε 08/11/2018 στις 00:13
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more