Javascript - omzetten geneste arrays in het doel van arrays

stemmen
1

Ik heb een geneste array met niet herkende. Hier is een voorbeeld:

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

De matrices hebben een lengte van 2 of groter. Een reeks kan elk aantal andere arrays die eveneens willekeurig aantal arrays kunnen bevatten. Alle waarden zijn ofwel strings of arrays.

Ik probeer dit om te zetten in een enkel object met de volgende vorm:

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

In principe elke reeks moet worden omgezet in een voorwerp waarbij de eerste waarde is de sleutel en de rest van de reeks de waarde. Ik heb geprobeerd met behulp van reduce, maar kan niet helemaal krijgen het recht.

De vraag is gesteld op 07/11/2018 om 23:44
bron van user
In andere talen...                            


6 antwoorden

stemmen
4

In dit geval, weet je niet hoe diep je geneste arrays zijn, dus het is een goed idee om een ​​recursieve functie te ontwerpen.

In het basisgeval van recursieve functie, de ingang geen array, zodat alleen de ingang weer.

In het geval dat het ingangssignaal een matrix, maken een JS object met één eigenschap waarvan de naam gelijk is aan het eerste element in de invoerarray, en waarvan de waarde gelijk is aan de rest van de matrix ... U moet recursief bellen uw functie tegen elk van de overige leden van hun waarde in de resulterende array te krijgen.

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

antwoordde op 08/11/2018 om 00:00
bron van user

stemmen
2

Iets zoals dit?

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

antwoordde op 08/11/2018 om 00:13
bron van user

stemmen
2

Just do it recursief als volgt:

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

De functie convertretourneert een object containg een sleutel-waardepaar. De sleutel is arr[0]de waarde van de overige elementen in de array ( arr.slice(1)) afgebeeld op een nieuwe array zodat convertheet alle arrayelementen binnen die array.

ES5 Versie:

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

Voorbeeld:

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

antwoordde op 08/11/2018 om 00:05
bron van user

stemmen
1

Aangezien u dit al getagd met lodashhier is een korte oplossing met het zo goed:

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>

Het is een recursieve oplossing lodash gebruikt .head het eerste element van de array te krijgen,.tail om alle, maar de eerste en krijgen dan_.mapelk van de elementen om over te gaan en terug te keren een array.

antwoordde op 08/11/2018 om 02:34
bron van user

stemmen
1

Deze efficiënte aanpak vermijdt het gebruik slice()(die een tijdelijke array van grootte zou leiden tot N-1 die wordt gedropt):

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

antwoordde op 08/11/2018 om 01:50
bron van user

stemmen
1

ES6: U kunt iets als het volgende te doen

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

Deze code definieert een functie convertArrayToObjectdie het element zelf terug als het geen array of stelt het eerste element als sleutel en roept de functie als de overige elementen met de waarde als het een array.

antwoordde op 08/11/2018 om 00:13
bron van user

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