Javascript - převod vnořených polí do předmětu polí

hlasů
1

Mám vnořené pole s neznámým tvaru. Zde je příklad:

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

Čipy mají délku 2 nebo větší. Pole může obsahovat libovolný počet dalších polí, které mohou také obsahovat libovolný počet polí. Všechny hodnoty jsou buď struny nebo matice.

Snažím se převést to do jednoho objektu s následujícím tvaru:

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

V podstatě, je třeba převést na objekt každého pole, kde první hodnota je klíčem a zbytek pole je hodnota. Snažil jsem se pomocí reduceale nelze úplně to pravé.

Položena 07/11/2018 v 23:44
zdroj uživatelem
V jiných jazycích...                            


6 odpovědí

hlasů
4

V tomto případě, nevíte, jak hluboko vaše vnořené sady jsou, takže je to dobrý nápad navrhnout rekurzivní funkce.

V základním případě Vašeho rekurzivní funkce, vstup není pole, takže stačí vrátit vstup.

V případě, že vstup je pole, vytvořit objekt JS s jediným majetkem, jehož název je stejný s prvním prvkem ve vstupním poli, a jehož hodnota je rovna zbytku pole ... Musíte rekurzivně volat vaše funkce proti každému ze zbývajících členů, aby si jejich hodnotu ve výsledné matice.

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

Odpovězeno 08/11/2018 v 00:00
zdroj uživatelem

hlasů
2

Něco takového?

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

Odpovězeno 08/11/2018 v 00:13
zdroj uživatelem

hlasů
2

Prostě to udělej rekurzivně jako tak:

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

Funkce convertvrátí objekt containg jeden pár klíč-hodnota. Klíčem je arr[0]a hodnota je zbytek prvků pole ( arr.slice(1)) mapované do nového pole tak, že convertse nazývá na všechny elementy pole uvnitř tohoto pole.

ES5 Version:

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

Příklad:

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

Odpovězeno 08/11/2018 v 00:05
zdroj uživatelem

hlasů
1

Vzhledem k tomu, označili to se lodashtady je krátký řešení s tím, jak dobře:

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>

Jedná se o řešení, které využívá rekurzivní lodash .head získat první prvek pole,.tail dostat všechno, ale jako první a pak_.mapjít přes všechny prvky a vrátit matici.

Odpovězeno 08/11/2018 v 02:34
zdroj uživatelem

hlasů
1

Tato efektivní přístup se vyhýbá použití slice()(což by vedlo k dočasné pole o velikosti N-1, který se spadl):

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

Odpovězeno 08/11/2018 v 01:50
zdroj uživatelem

hlasů
1

ES6: Můžete udělat něco jako následující

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

Tento kód definuje funkci convertArrayToObject, která vrací hodnotu sám, pokud to není pole nebo nastaví první prvek jako klíč a volá funkci, pokud se zbývajícími prvky, jako jsou hodnoty, jestli je to pole.

Odpovězeno 08/11/2018 v 00:13
zdroj uživatelem

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