688 Stimmen

Zugriff auf verschachtelte JavaScript-Objekte und -Arrays über einen String-Pfad

Ich habe eine Datenstruktur wie diese:

var someObject = {
    'part1' : {
        'name': 'Part 1',
        'size': '20',
        'qty' : '50'
    },
    'part2' : {
        'name': 'Part 2',
        'size': '15',
        'qty' : '60'
    },
    'part3' : [
        {
            'name': 'Part 3A',
            'size': '10',
            'qty' : '20'
        }, {
            'name': 'Part 3B',
            'size': '5',
            'qty' : '20'
        }, {
            'name': 'Part 3C',
            'size': '7.5',
            'qty' : '20'
        }
    ]
};

Und ich möchte mit diesen Variablen auf die Daten zugreifen:

var part1name = "part1.name";
var part2quantity = "part2.qty";
var part3name1 = "part3[0].name";

part1name sollte gefüllt werden mit someObject.part1.name Wert, der "Teil 1" ist. Dasselbe gilt für part2quantity, das mit 60 gefüllt ist.

Gibt es irgendwie zu erreichen dies entweder mit reinen Javascript oder JQuery?

0 Stimmen

Sie sind sich nicht sicher, was Sie hier fragen? Möchten Sie part1.name abfragen können und den Text "part1.name" zurückerhalten? Oder möchten Sie den in part1.name gespeicherten Wert abrufen?

0 Stimmen

Haben Sie versucht, etwas zu tun wie var part1name = someObject.part1name; `

1 Stimmen

@BonyT : Ich möchte someObject.part1.name abfragen und den Wert davon zurückgeben ("Part 1"). Ich möchte jedoch, dass die Abfrage (ich nannte sie "den Schlüssel") in einer Variablen 'part1name' gespeichert wird. Vielen Dank für Ihre Antwort. @3nigma : Das habe ich sicherlich. Aber das ist nicht meine Absicht. Vielen Dank für die Antwort.

1voto

georgeawg Punkte 47865

AngularJS hat $scope.$eval

Mit AngularJS kann man die $scope.$eval Methode, um auf verschachtelte Objekte zuzugreifen:

$scope.someObject = someObject;
console.log( $scope.$eval("someObject.part3[0].name") ); //Part 3A

Weitere Informationen finden Sie unter

Die DEMO

angular.module("app",[])
.run(function($rootScope) {
     $rootScope.someObject = {
         'part2' : {
              'name': 'Part 2',
              'size': '15',
              'qty' : '60'
         },
         'part3' : [{
              'name': 'Part 3A',
              'size': '10',
              'qty' : '20'
         },{
              name: 'Part 3B'           
         }]
     };
     console.log(
         "part3[0].name =",
         $rootScope.$eval("someObject.part3[0].name")
    );
})

<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app"
</body>

1voto

Vincent Punkte 2262

Auf der Grundlage einer früheren Antwort habe ich eine Funktion erstellt, die auch mit Klammern umgehen kann. Aber wegen der Aufteilung gibt es keine Punkte in ihnen.

function get(obj, str) {
  return str.split(/\.|\[/g).map(function(crumb) {
    return crumb.replace(/\]$/, '').trim().replace(/^(["'])((?:(?!\1)[^\\]|\\.)*?)\1$/, (match, quote, str) => str.replace(/\\(\\)?/g, "$1"));
  }).reduce(function(obj, prop) {
    return obj ? obj[prop] : undefined;
  }, obj);
}

1voto

sam Punkte 738

Erweiterung von Mohamad Hamouday' Antwort wird fehlende Schlüssel ergänzen

function Object_Manager(obj, Path, value, Action, strict) 
{
    try
    {
        if(Array.isArray(Path) == false)
        {
            Path = [Path];
        }

        let level = 0;
        var Return_Value;
        Path.reduce((a, b)=>{
            console.log(level,':',a, '|||',b)
            if (!strict){
              if (!(b in a)) a[b] = {}
            }

            level++;
            if (level === Path.length)
            {
                if(Action === 'Set')
                {
                    a[b] = value;
                    return value;
                }
                else if(Action === 'Get')
                {
                    Return_Value = a[b];
                }
                else if(Action === 'Unset')
                {
                    delete a[b];
                }
            } 
            else 
            {
                return a[b];
            }
        }, obj);
        return Return_Value;
    }

    catch(err)
    {
        console.error(err);
        return obj;
    }
}

Beispiel

obja = {
  "a": {
    "b":"nom"
  }
}

// Set
path = "c.b" // Path does not exist
Object_Manager(obja,path.split('.'), 'test_new_val', 'Set', false);

// Expected Output: Object { a: Object { b: "nom" }, c: Object { b: "test_new_value" } }

1voto

Mohamad Hamouday Punkte 1396

Inspiriert durch die Antwort von @webjay: https://stackoverflow.com/a/46008856/4110122

Ich habe diese Funktion erstellt, die Sie verwenden können, um Holen/ Setzen/ Rücksetzen beliebiger Wert im Objekt

function Object_Manager(obj, Path, value, Action) 
{
    try
    {
        if(Array.isArray(Path) == false)
        {
            Path = [Path];
        }

        let level = 0;
        var Return_Value;
        Path.reduce((a, b)=>{
            level++;
            if (level === Path.length)
            {
                if(Action === 'Set')
                {
                    a[b] = value;
                    return value;
                }
                else if(Action === 'Get')
                {
                    Return_Value = a[b];
                }
                else if(Action === 'Unset')
                {
                    delete a[b];
                }
            } 
            else 
            {
                return a[b];
            }
        }, obj);
        return Return_Value;
    }

    catch(err)
    {
        console.error(err);
        return obj;
    }
}

Zur Verwendung:

 // Set
 Object_Manager(Obj,[Level1,Level2,Level3],New_Value, 'Set');

 // Get
 Object_Manager(Obj,[Level1,Level2,Level3],'', 'Get');

 // Unset
 Object_Manager(Obj,[Level1,Level2,Level3],'', 'Unset');

1voto

Oboo Cheng Punkte 3900
// (IE9+) Two steps

var pathString = "[0]['property'].others[3].next['final']";
var obj = [{
  property: {
    others: [1, 2, 3, {
      next: {
        final: "SUCCESS"
      }
    }]
  }
}];

// Turn string to path array
var pathArray = pathString
    .replace(/\[["']?([\w]+)["']?\]/g,".$1")
    .split(".")
    .splice(1);

// Add object prototype method
Object.prototype.path = function (path) {
  try {
    return [this].concat(path).reduce(function (f, l) {
      return f[l];
    });
  } catch (e) {
    console.error(e);
  }
};

// usage
console.log(obj.path(pathArray));
console.log(obj.path([0,"doesNotExist"]));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X