根据唯一ID确定是否推送或更新数组中的对象

Determine whether to push or update object in array based on unique ID

我正在尝试编写一个基本函数,该函数将根据此对象内部的唯一 ID 确定对象是否已存在于对象数组中,作为 属性。经过搜索,我想到了这段代码,它似乎工作正常,但我可以想象有一种更好更快的方法来确定是推送还是更新对象。如果您可以分享您对此的最佳答案,请...

var myArray = [
  {
    id: 1,
    car: "Ford"
  },
  {
    id: 2,
    car: "Honda"
  }
];

var objToOverwrite = {
  id: 1,
  car: "Bentley" // to overwrite car: "Ford"
};

var objToPush = {
  id: 3,
  car: "Toyota"
};


function pushToArray ( arr, obj ) {


  var existingIds = arr.map((obj) => obj.id);

    if (! existingIds.includes(obj.id)) {
      arr.push(obj);
    } else {
      arr.forEach((element, index) => {
        if (element.id === obj.id) {
          arr[index] = obj;
        };
      });
    };
};

pushToArray ( myArray, objToPush );

console.log(myArray);

如果您想将其减少到 1 次迭代,您可以这样做: (请注意,这是您代码的不可变版本,因此它将 return 一个包含您的结果的新数组,而不是改变原始数组)

function pushToArray ( arr, obj ) {
  let updated = false

  let result = arr.map(el => {
    if (obj.id === el.id) {
      updated = true
      return obj
      // or maybe you want to merge objects here? return Object.assign({}, el, obj)
    }

    return el
  })

  if (!updated) {
    result.push(obj)
  }

  return result
}

您还可以考虑使用由 id 键入的对象而不是数组。它会简化逻辑:

let cars = {
  1: {
    id: 1,
    car: 'Ford',
  },
  2: {
    id: 2,
    car: 'Honda',
  }
}

function updateData ( data, obj ) {
  // again, an immutable version. You can make this mutable by removing the first {}
  return Object.assign({}, data, {
    [obj.id]: obj
  })
}

并且您始终可以在需要时将值转换为数组:

Object.values(cars) // => your original array

设法用好的旧香草 JS 更好地编码:

function pushToArray(arr, obj) {
 var value = obj.id;
 var found = false;
  for (var i = 0; i < arr.length; i++) {
    if (arr[i].id === value) {
      arr[i] = obj;
      found = true;
    }     
  };
  if (!found) arr.push(obj);
};

var myArray = [
  {
    id: 1,
    car: "Ford"
  },
  {
    id: 2,
    car: "Honda"
  }
];

var objToOverwrite = {
  id: 1,
  car: "Bentley" // to overwrite car: "Ford"
};

var objToPush = {
  id: 3,
  car: "Toyota"
};

pushToArray(myArray, objToOverwrite);

console.log(myArray);