Javascript - 向对象添加对象 - 如何处理数组?

时间:2017-09-14 01:29:37

标签: javascript arrays angular lodash

使用javascript对象,我正在努力弄清楚如何向它添加新数据(特别是更多对象)。在添加数据时,我不确定如何将现有值转换为对象数组。

以下是我的对象示例:

它很直接,此时不包含任何数组。这就是我被卡住的地方。

var obj = {
  "data": {
    "VersionForTarget": "1",
    "RulesContainer": {
      "Rule": { // <--- New Rule Goes Here
        "RuleParentID": "1",
        "RuleVersionID": "1",
        "MappedValue": "1",
        "ProcessingOrder": "1",
        "MetaInsertUtc": "2017-03-03T17:54:34.643",
        "Value": "Omaha",
        "IsRuleRetired": "0",
        "UserImpactCount": "2277",
        "AttributeContainer": {
          "Attribute": { // <--- New Attribute Goes Here
            "AttributeID": "6",
            "AttributeName": "Campus",
            "AttributeDetailsContainer": {
              "AttributeDetails": { // <--- New Attribute Details Goes Here
                "RuleDetailID": "1",
                "AttributeID": "6",
                "OperatorID": "3",
                "AttributeValue": "1",
                "RuleParentID": "1",
                "Value": "Omaha",
                "IsValueRetired": "0",
                "OperatorName": "In List",
                "SqlOperator": "IN"
              }
            }
          }
        }
      }
    }
  }
};

如果我想向Rule添加新的数据对象,Rule则成为Rule个对象的数组。

我想要的是什么:

我基本上试图制作三个功能。一个将添加Rule,一个将Attribute添加到指定规则,另一个将AttributeDetails添加到指定规则中的指定属性。

// This will add a new rule
function addRule() {

  var newRule = {
    "RuleParentID": "3",
    "RuleVersionID": "1",
    "MappedValue": "4",
    "ProcessingOrder": "5",
    "MetaInsertUtc": "2017-03-03T17:54:34.643",
    "Value": "New Thing",
    "IsRuleRetired": "0",
    "UserImpactCount": "2277"
  };

}


// This will add a new attribute
function addAttribute(RuleParentID) {

  // Add attribute object in our parent rule

  var newAttribute = {
    "AttributeID": "6",
    "AttributeName": "Campus",
  }

}


// This will add new attribute details
function addAttributeDetails(RuleParentID, AttributeID) {

  // Add attribute details to our specified attribute in our specified parent rule

  var newAttributeDetails = {
    "RuleDetailID": "1",
    "AttributeID": "6",
    "OperatorID": "3",
    "AttributeValue": "1",
    "RuleParentID": "1",
    "Value": "Omaha",
    "IsValueRetired": "0",
    "OperatorName": "In List",
    "SqlOperator": "IN"
  }

}

我的问题

我可以采取哪些方法来拍摄这样的照片?我想过循环遍历数据RuleContainer,但Rule可能是也可能不是数组。

我已经阅读了lodash的一些文档,并使用了_find之类的一些函数来至少在我需要操作的地方找到方向但是我不能弄清楚从哪里去。

有什么建议吗?

以下是此设置的一个小提琴,其中包含使用此类工作函数可能获得的结果示例。

https://jsfiddle.net/tor1t2q6/1/

3 个答案:

答案 0 :(得分:1)

要解决您的问题,您可以让RuleContainer成为数组而不是对象。

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;

namespace ConsoleApp11
{
    class Program
    {

        static void Main(string[] args)
        {
            //var EmployeeIDs = File.ReadAllLines(""/* Filepath */);
            var EmployeeIDs = Enumerable.Range(1, 30 * 1000).ToList();
            var dt = new DataTable();
            dt.Columns.Add("id", typeof(int));

            dt.BeginLoadData();
            foreach (var id in EmployeeIDs)
            {
                var row = dt.NewRow();
                row[0] = id;
                dt.Rows.Add(row);
            }
            dt.EndLoadData();

            using (SqlConnection conn = new SqlConnection("server=.;database=tempdb;integrated security=true"))
            {
                conn.Open();

                var cmdCreateTemptable = new SqlCommand("create table #ids(id int primary key)",conn);
                cmdCreateTemptable.ExecuteNonQuery();

                //var cmdCreateEmpable = new SqlCommand("create table Employees(EmployeeId int primary key, FirstName varchar(2000))", conn);
                //cmdCreateEmpable.ExecuteNonQuery();


                var bc = new SqlBulkCopy(conn);
                bc.DestinationTableName = "#ids";
                bc.ColumnMappings.Add("id", "id");
                bc.WriteToServer(dt);

                var names = new List<string>();
                var cmd = new SqlCommand("SELECT FirstName, EmployeeId FROM Employees WHERE EmployeeID in (select id from #ids)", conn);
                using (var rdr = cmd.ExecuteReader())
                {
                    var firstName = rdr.GetString(0);
                    var id = rdr.GetInt32(1);
                    names.Add(firstName);
                }

                Console.WriteLine("Hit any key to continue");
                Console.ReadKey();
            }



        }


    }
}

答案 1 :(得分:0)

我按照我认为你要问的方式改变了你的小提琴。它的要点是你可以改变规则&#39;从一开始就将对象放入一个数组中,然后不用担心它,无论最初是作为数组还是对象给出规则,它都应该有效。

X = np.asarray(train_data['presence_vector'])
X.reshape((4,16))
X = train_data['presence_vector'].values
X.reshape((4,16))
X = train_data['presence_vector'].as_matrix()
X.reshape((4,16))

然后从那里开始添加你的函数,根据需要修改数组(和数组中的对象)。这里遍历数组以找到正确的ID,然后将新属性添加到该对象。

const objectWithRuleAsArray = initRuleArray(obj);
function initRuleArray(object) {
    if(Array.isArray(object.data.RulesContainer.Rule)) {
    return object;
  } else {
    const ruleData = object.data.RulesContainer.Rule;
    object.data.RulesContainer.Rule = []
    object.data.RulesContainer.Rule.push(ruleData);
    return object;
  }
}
let rulesArray = objectWithRuleAsArray.data.RulesContainer.Rule
rulesArray.push(addRule());
console.log('Created Rules Array & Added Rule', rulesArray);

修改过的小提琴:https://jsfiddle.net/04podo35/2/

答案 2 :(得分:0)

由于您没有提及存储和更新JSON数据的目的,我将假设数据用于简单的CRUD操作。如果是这种情况,那么最好考虑改变整个JSON结构。主要原因:

  • 难以执行简单的操作:基于对象的ID,大多花费O(n)时间执行搜索/删除;你总是需要循环整个数组来获得匹配的数组。
  • 重复数据:只要您想将属性添加到多个规则,属性就可能会重复;同样适用于AttributeDetail。这也会增加插入操作的复杂性。
  • 嵌套数据结构:嵌套规则,属性和属性详细信息在执行操作时会花费很多。维持它也将是一件苦差事。

我的建议:不要使用数组。使用ID作为键存储规则,属性和属性详细信息。这样,您无需担心对象是否为数组;它也有助于简化简单的CRUD操作。以下是使用RuleVersionID,AttributeID和RuleDetailID-AttributeID组合来存储相同数据的示例。

var obj = {
  "data": {
    "VersionForTarget": "1",
    "RulesContainer": {
      "Rule": { // <--- New Rule Goes Here
        "1": { 
          "RuleParentID": "1",
          "RuleVersionID": "1",
          "MappedValue": "1",
          "ProcessingOrder": "1",
          "MetaInsertUtc": "2017-03-03T17:54:34.643",
          "Value": "Omaha",
          "IsRuleRetired": "0",
          "UserImpactCount": "2277",
          "AttributeContainer": {
            "Attribute": { // <--- New Attribute Goes Here
              "6": {
                "AttributeID": "6",
                "AttributeName": "Campus",
                "AttributeDetailsContainer": {
                  "AttributeDetails": { // <--- New Attribute Details Goes Here
                    "1-6": {
                      "RuleDetailID": "1",
                      "AttributeID": "6",
                      "OperatorID": "3",
                      "AttributeValue": "1",
                      "RuleParentID": "1",
                      "Value": "Omaha",
                      "IsValueRetired": "0",
                      "OperatorName": "In List",
                      "SqlOperator": "IN"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
};

只要有助于识别对象,您就可以使用任何其他属性作为键。

所以你的函数addRule看起来像这样(这里我使用了2个lodash方法:sethas

function addRule(newRule) {
  if (has(newRule, "ruleVersionID")) {
    var path = "data.RuleContainer.Rule." + newRule.ruleVersionID;
    set(obj, path, newRule); 
    return path;
  }
  return null;
}

我还强烈建议您展平数据:将Rule,Attribute,AttributeDetail保持在同一级别。这是一个让他们彼此远离的例子:

var obj = {
  "data": {
    "VersionForTarget": "1",
    "RulesContainer": {
      "Rule": {
        "1": {
          "RuleParentID": "1",
          "RuleVersionID": "1",
          "MappedValue": "1",
          "ProcessingOrder": "1",
          "MetaInsertUtc": "2017-03-03T17:54:34.643",
          "Value": "Omaha",
          "IsRuleRetired": "0",
          "UserImpactCount": "2277"
        }
      }
    },
    "AttributeContainer": {
      "Attribute": {
        "6": {
          "AttributeID": "6",
          "AttributeName": "Campus",
        }
      }
    },
    "AttributeDetailsContainer": {
      "AttributeDetails": {
        "1-6": {
          "RuleDetailID": "1",
          "AttributeID": "6",
          "OperatorID": "3",
          "AttributeValue": "1",
          "RuleParentID": "1",
          "Value": "Omaha",
          "IsValueRetired": "0",
          "OperatorName": "In List",
          "SqlOperator": "IN"
        }
      }
    }
  }
};

有关详细信息,请阅读this documentation有关JSON规范化的信息。这就是我的解决方案来源。