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

时间:2018-09-12 06:23:03

标签: javascript arrays angularjs loops object

我正在使用Angular javascript完成一项任务,该任务需要从click函数数组中更新JSON键值。

我有这样的 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"
    }
};

我有一个数组$scope.textvalue=["center", "80mm","150%"]。因此,在这里我想根据索引更新JSON的键值__text。意味着我想根据JSON和数组中的__text索引来推送数组详细信息。

我是通过在控制器中单击按钮来执行此操作的。

$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]);
}

我做了$scope.jsonObj[$scope.objIndex].__text = ???;因为我不知道该怎么办,并且由于 $ scope.jsonObj.findIndex不是函数

建议我采用某种方式来更新JSON值。

3 个答案:

答案 0 :(得分:1)

我会这样做。我创建了一个像您一样的函数(除了它现在不在AngularJS中,但您可以很容易地实现它)。

将索引传递给函数,它将迭代__text的出现并找出将值放置在何处。

这是有效的代码段:(当我传递相应的索引时,请参见最后一个/第三个150%值中的__text

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

答案 1 :(得分:1)

主要问题是attribute可以是对象文字或对象文字数组。这是一个通过比较__text遍历jsonObj并返回对所讨论属性的引用的函数。如果未找到任何内容,则会添加新属性并返回:

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
}

示例:

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

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

答案 2 :(得分:1)

您可以通过使用 Array.forEach() method 遍历$scope.jsonObj.stylesheet["attribute-set"]数组并分别为每个"__text"对象更新相关的attribute属性来做到这一点/ array。

  • 我使用了 Array#isArray() method 来检查迭代的attribute属性是array还是object
  • 我将$scope.textvalue数组复制到arr中并使用了 Array#shift() method ,以在每次迭代中从arr数组中获取相关值。

这应该是您的代码:

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

演示:

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