【问题标题】:Operating on one of the objects in the array based on a field基于字段对数组中的一个对象进行操作
【发布时间】:2020-02-05 07:04:30
【问题描述】:

有一个具有上述结构的对象。有了这个对象,我需要操纵对象“prop21”数组中存在的对象之一。

let obj = {
    prop: {
        prop21: [
            {
                field: "val1",
                value1: "val2"
            }
        ]
    }
}

以下场景:

每当我将“ack”传递给函数时

1) 我需要创建一个格式为 { field: "ack" , value : true } 的对象并将其推送到 prop21 数组,以防不存在 { field: "ack" , value : true } 的对象.

2) 如果存在 { field: "ack" , value : false },则将 value 转换为 true

当我将“unack”传递给函数时

1) 我需要创建一个格式为 { field: "ack" , value : false } 的对象并将其推送到 prop21 数组,以防不存在 { field: "ack" , value : false } 的对象.

2) 如果存在 { field: "ack" , value : true },则将 value 转换为 false

当我将“全部”传递给函数时

它应该基本上删除 object { field :"ack" , value : true} 或 {field: "ack" , value: false} 如果存在

function manipulate(val) {

    let newObj = { field: "ack", operator: "=", value: true }
    if (value === "ack") {
        // change the "value" field of object with field:"ack" to true if its present, else create a new one with format of "newObj" with value true and push it
    }
    else if (value === "unack") {
        // change the "value" field of object with field:"ack" to false if its present, else create a new one with format of "newObj" with valye false and push it
    }
    else {
        //this is case for value === "all" , hence remove the object with field with value "ack"
    }
}

【问题讨论】:

  • 你是否在程序的另一个地方对数组进行了变异?
  • @NinaScholz 是的,我也使用相同的数组和其他函数。基本上我在全局声明了 obj,所以所有函数都会共享它

标签: javascript ecmascript-6 ecmascript-5


【解决方案1】:

在代码本身中添加注释以进行解释。希望这会有所帮助。

let obj = {
  prop: {
    prop21: [
      {
        field: "val1",
        value1: "val2"
      }
    ]
  }
};

function manipulate(val) {
  // value = true for ack and false for unack.
  const newObj = { field: "ack", value: val === "ack" };
  // first remove field: ack for all val cases ack, unack, all.
  obj.prop.prop21 = obj.prop.prop21.filter(prop => !prop.field.includes("ack"));
  // ack and unack will contain 'ack', so checking for ack.
  if (val.includes("ack")) {
    // add it for ack/unack cases.
    obj.prop.prop21.push(newObj);
  }
}

manipulate("ack");
console.log(obj);
manipulate("unack");
console.log(obj);
manipulate("all");
console.log(obj);

【讨论】:

  • 一开始删除 ack 字段很聪明。它快速而直接,并达到相同的结果。 +1
  • 这种方法改变了数组的顺序,并为每个调用创建一个新的对象引用(过滤)。
【解决方案2】:

很简单。解释在 cmets 中

let obj = {
    prop: {
        prop21: [
            {
                field: "val1",
                value1: "val2"
            },
            {
                "field": "ack",
                "operator": "=",
                "value": null
            }
        ]
    }
}

function manipulate(value) {
    const newobj = { field: "ack", operator: "=", value: false };
    if (value === "ack") toggleAck(newobj, true);
    else if (value === "unack") toggleAck(newobj, false);
    else removeAck();
}

function toggleAck(newobj, val) {
    newobj.value = val; //modify value of new ack object based on ack/unack
    const ackItem = obj.prop.prop21.find(i => i.field == "ack"); //look for object with ack field
    if (ackItem) ackItem.value = val; //if exists, change this object value
    else obj.prop.prop21.push(newobj); //else, push new obj from template
}

function removeAck() {
    const ackItemIdx = obj.prop.prop21.findIndex(i => i.field == "ack");  //look for object with ack field
    obj.prop.prop21.splice(ackItemIdx, 1); //remove item from array
}

manipulate("ack");
console.log(obj.prop.prop21);
manipulate("unack");
console.log(obj.prop.prop21);
manipulate("all");
console.log(obj.prop.prop21);

我制作了单独的函数,以便于阅读。您可以根据自己的出价对其进行优化/重构

【讨论】:

    【解决方案3】:

    let obj = {
      prop: {
        prop21: [{
          field: "val1",
          value1: "val2"
        }]
      }
    }
    
    
    function manipulate(value) {
      let newObj = {
        field: "ack",
        operator: "=",
        value: true
      }
      let isAck = false;
      let index = -1;
      
      let myarr = obj.prop.prop21;
      for(let i =0;i< myarr.length;i++){
      	if (myarr[i].field === 'ack') {
          isAck = true;
          index = i;
          break;
        }
      }
      if (value === "ack") {
    
        if (isAck) {
          let prop21obj = obj.prop.prop21[index];
          obj.prop.prop21[index] = Object.assign(prop21obj, newObj);
        } else {
          obj.prop.prop21.push(newObj);
        }
        // change the "value" field of object with field:"ack" to true if its present, else create a new one with format of "newObj" with value true and push it
      } else if (value === "unack") {
    
    
        newobj[value] = false;
    
        if (isAck) {
          let prop21obj = obj.prop.prop21[index];
    
          obj.prop.prop21[index] = Object.assign(prop21obj, newObj);
        } else {
          obj.prop.prop21.push(newObj);
        }
    
        // change the "value" field of object with field:"ack" to false if its present, else create a new one with format of "newObj" with valye false and push it
      } else {
    
        if (isAck) {
    
          obj.prop.prop21.splice(index, 1);
        }
        //this is case for value === "all" , hence remove the object with field with value "ack"
      }
    }
    
    manipulate('ack');
    console.log(obj);

    【讨论】:

      【解决方案4】:

      您可以通过查找对象并使用switch 更新类型来采取直接的方法。

      function change(array, type) {
          var index = array.findIndex(({ field }) => field === 'ack'),
              temp = array[index] || { field: "ack", value: type === "ack" };
      
          switch (type) {
              case 'ack':
              case 'unack':
                  if (index !== -1) temp.value = type === "ack";
                  else array.push(temp);
                  break;
              case 'all':
                  if (index !== -1) array.splice(index, 1);
          }
      }
      
      let obj = { prop: { prop21: [{ field: "val1", value1: "val2" }] } };
      
      change(obj.prop.prop21, 'ack');
      console.log(obj.prop.prop21);
      
      change(obj.prop.prop21, 'unack');
      console.log(obj.prop.prop21);
      
      change(obj.prop.prop21, 'ack');
      console.log(obj.prop.prop21);
      
      change(obj.prop.prop21, 'all');
      console.log(obj.prop.prop21);
      .as-console-wrapper { max-height: 100% !important; top: 0; }

      【讨论】:

      • 如果 type == 'ack',你在 ack 的情况下什么也没做
      • 它与'unack'的大小写相同并更新或推送。
      • 我很感激。
      • 这是一种失败的方法。
      • 只在最后加一个,不过是多余的,因为default:是一个空子句。
      猜你喜欢
      • 2021-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-08
      • 2019-01-07
      • 2014-04-01
      • 2019-04-10
      • 1970-01-01
      相关资源
      最近更新 更多