简体   繁体   English

通过索引从数组更新JSON键值

[英]Updating JSON key value from an array by index

I am using Angular javascript to accomplish a task where I need to update a JSON key value from an array on click function. 我正在使用Angular javascript完成一项任务,该任务需要从click函数数组中更新JSON键值。

I have JSON structure like this:- 我有这样的JSON结构:-

$scope.jsonObj = {
    "stylesheet": {
        "attribute-set": [{
                "attribute": {
                    "_name": "text-align",
                    "__prefix": "xsl",
                    "__text": "center"
                },
                "_name": "__frontmatter",
                "__prefix": "xsl"
            },
            {
                "attribute": [{
                        "_name": "space-before",
                        "__prefix": "xsl",
                        "__text": "80mm"
                    },
                    {
                        "_name": "line-height",
                        "__prefix": "xsl",
                        "__text": "140%"
                    }
                ],
                "_name": "__frontmatter__title",
                "_use-attribute-sets": "common.title",
                "__prefix": "xsl"
            }
        ],
        "_version": "2.0",
        "__prefix": "xsl"
    }
};

I have an array $scope.textvalue=["center", "80mm","150%"] . 我有一个数组$scope.textvalue=["center", "80mm","150%"] So here I want to update the key value __text of the JSON according to index. 所以在这里我想根据索引更新JSON的键值__text Means i want to push the array details according to index of __text in the JSON and array. 意味着我想根据JSON和数组中__text索引推送数组详细信息。

I am doing this on button click in controller . 我正在控制器中单击按钮时执行此操作。

$scope.save = function(index) {
    $scope.textvalue[index];
    console.log($scope.textvalue);
    $scope.objIndex = $scope.jsonObj.findIndex((obj => obj.__text));
    console.log("Before update: ", $scope.jsonObj[$scope.objIndex]);
    $scope.jsonObj[$scope.objIndex].__text = ? ? ? ;
    console.log("After update: ", $scope.jsonObj[$scope.objIndex]);
}

I did $scope.jsonObj[$scope.objIndex].__text = ??? 我做了$scope.jsonObj[$scope.objIndex].__text = ??? ; ; as I don't know what to do here and I have an error as $scope.jsonObj.findIndex is not a function 因为我不知道该怎么办,并且因为$ scope.jsonObj.findIndex不是函数 ,所以出现错误

Suggest me some way to update my JSON value. 建议我一些更新我的JSON值的方法。

I would do it like this. 我会这样做。 I created a function like you (except it's not in AngularJS right now, but you can very easily make it). 我创建了一个像您一样的函数(除了它现在不在AngularJS中,但您可以很容易地实现它)。

You pass the index to the function, it will iterate over the occurances of __text and figure out where to put the value. 您将索引传递给函数,它将遍历__text并找出将值放在何处。

Here's the working snippet: (see the 150% in the last/3rd __text value when I pass corresponding index) 这是工作片段:(当我传递相应的索引时,请参阅上一个/第三个__text值中的150%

 let jsonObj = { "stylesheet": { "attribute-set": [{ "attribute": { "_name": "text-align", "__prefix": "xsl", "__text": "center" }, "_name": "__frontmatter", "__prefix": "xsl" }, { "attribute": [{ "_name": "space-before", "__prefix": "xsl", "__text": "80mm" }, { "_name": "line-height", "__prefix": "xsl", "__text": "140%" } ], "_name": "__frontmatter__title", "_use-attribute-sets": "common.title", "__prefix": "xsl" } ], "_version": "2.0", "__prefix": "xsl" } }; let textvalue = ["center", "80mm", "150%"]; let textvalueIndex = 0; function save(index) { let updated = jsonObj.stylesheet['attribute-set'].reduce(function(agg, obj) { if (Array.isArray(obj.attribute)) { for (let i = 0; i < obj.attribute.length; i++) { if (textvalueIndex === index) { obj.attribute[i].__text = textvalue[textvalueIndex]; } textvalueIndex++; } } else { if (textvalueIndex === index) { obj.attribute.__text = textvalue[textvalueIndex]; } textvalueIndex++; } agg.push(obj); return agg; }, []) console.log(updated) } save(2) // third item in textvalue array will be saved on the third occurance of __text 

The main problem is that attribute can be either an object literal or an array of object literals. 主要问题是attribute可以是对象文字或对象文字数组。 Here is a function that travels through jsonObj by comparing __text and return a reference to the attribute in question. 这是一个通过比较__text并返回对所讨论属性的引用的函数。 If nothing is found, a new attribute is added and returned instead : 如果未找到任何内容,则会添加新属性并返回:

function getAttribute(__text) {
  var attributes = $scope.jsonObj['stylesheet']['attribute-set']; 
  for (var i=0, l=attributes.length; i<l; i++) {
    var attribute = attributes[i].attribute;
    if (attribute.length) {  //array of attributes
       for (attr in attribute) {
         if (attribute[attr].__text == __text) return attribute[attr]
       }
    } else {  //attribute literal
      if (attribute.__text == __text) return attribute
    } 
  }
  var index = attributes.push({  
    attribute: { __text: __text } 
  });
  return attributes[i].attribute
}

example: 例:

var center = getAttribute('center');
center.NEW_VALUE = 'TEST';

var new_attr = getAttribute('new_attr');
new_attr.__prefix = 'SOMETHING';  

You can do it by iterating over the $scope.jsonObj.stylesheet["attribute-set"] array using Array.forEach() method and updating the relevant "__text" properties, respectively for each attribute object/array. 您可以使用Array.forEach()方法遍历$scope.jsonObj.stylesheet["attribute-set"]数组并分别为每个attribute对象/数组更新相关的"__text"属性来完成此操作。

  • I used Array#isArray() method to check if the iterated attribute property is an array or an object . 我使用Array#isArray()方法来检查迭代attribute属性是array还是object
  • I copied the $scope.textvalue array into arr and used Array#shift() method to get the relevant value from the arr array in each iteration. 我将$scope.textvalue数组复制到arr并使用Array#shift()方法在每次迭代中从arr数组中获取相关值。

This is how should be your code: 这应该是您的代码:

const arr = $scope.textvalue.slice();
$scope.jsonObj.stylesheet["attribute-set"].forEach(function(a) {
  if (Array.isArray(a.attribute)) {
    a.attribute.forEach(att => att["__text"] = arr.shift());
  } else {
    a.attribute["__text"] = arr.shift();
  }
});

Demo: 演示:

 $scope= {}; $scope.jsonObj = { "stylesheet": { "attribute-set": [{ "attribute": { "_name": "text-align", "__prefix": "xsl", "__text": "center" }, "_name": "__frontmatter", "__prefix": "xsl" }, { "attribute": [{ "_name": "space-before", "__prefix": "xsl", "__text": "80mm" }, { "_name": "line-height", "__prefix": "xsl", "__text": "140%" } ], "_name": "__frontmatter__title", "_use-attribute-sets": "common.title", "__prefix": "xsl" } ], "_version": "2.0", "__prefix": "xsl" } }; $scope.textvalue = ["center", "80mm", "150%"]; const arr = $scope.textvalue.slice(); $scope.jsonObj.stylesheet["attribute-set"].forEach(function(a) { if (Array.isArray(a.attribute)) { a.attribute.forEach(att => att["__text"] = arr.shift()); } else { a.attribute["__text"] = arr.shift(); } }); console.log($scope.jsonObj); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM