如果项目具有相同的ID,则将项目添加到数组或替换它

时间:2017-08-02 11:32:02

标签: javascript arrays object

我有这个对象数组

var source = [
  {id: 1, label: "one"},
  {id: 2, label: "two"},
  {id: 3, label: "three"}
];

我需要添加一个项目,如果它具有相同的ID

,则替换它
var new_sub = {id: 1, label: "new label for one"};
var new_add = {id: 4, label: "four"};

source = myFunc(new_sub);
source = myFunc(new_add);

function myFunc(obj) {
  return (source.findIndex(x => x.id === obj.id) === -1) ? 
  source.concat(obj) : source.map((item) => {
    return (item.id === obj.id) ? obj : item;
  });
}

此代码运行良好,但有更好的方法吗? 你可以检查我的代码到这个snippit:

var source = [
      {id: 1, label: "one"},
      {id: 2, label: "two"},
      {id: 3, label: "three"}
    ];
var new_sub = {id: 1, label: "new label for one"};
var new_add = {id: 4, label: "four"};

source = myFunc(new_sub);
source = myFunc(new_add);

function myFunc(obj) {
  return (source.findIndex(x => x.id === obj.id) === -1) ? 
  	source.concat(obj) : source.map((item) => {
    	return (item.id === obj.id) ? obj : item;
    });
}

//PRINT
var html = "";
source.map((item) => {
	html += "<li>" + item.id + " - " + item.label + "</li>";
});
$("#resp").html(html);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="resp">
</ul>

4 个答案:

答案 0 :(得分:1)

function myFunc(obj) {
  let i = source.findIndex(x => x.id === obj.id); // get the index
  if(i === -1) sources.push(obj);                 // if there isn't any object that have the same id, then push this obj into the array
  else sources[i] = obj;                          // if there is then replace it
  return sources;                                 // this won't be necessary the array get mutated so no need to store it back into sources (see note bellow)
}

注意:您的myFunc版本每次调用时都会创建一个新数组。我的版本没有。但是,由于您将myFunc的返回值存回sources,我认为不需要创建新数组(在我的版本中,您不必做{{1}当数组sources = myFunc(...)变异时。)

较旧的浏览器支持:(实际上更好)

&#13;
&#13;
sources
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您正在对阵列进行多次传递(一个位于findIndex,一个位于concatmap),这是不必要的。只需一次通过即可:

function myFunc(a, obj) {
  let found = false;
  const result = a.map(e => {
    if (!found && e.id === obj.id) {
      found = true;
      return obj;
    } else {
      return e;
    }
  });
  if (!found) {
    result.push(obj);
  }
  return result;
}

请注意,我将源数组作为参数传递给函数,因此它没有副作用。

var source = [
  {id: 1, label: "one"},
  {id: 2, label: "two"},
  {id: 3, label: "three"}
];

var new_sub = {id: 1, label: "new label for one"};
var new_add = {id: 4, label: "four"};

source = myFunc(source, new_sub);
source = myFunc(source, new_add);

console.log(source);

function myFunc(a, obj) {
  let found = false;
  const result = a.map(e => {
    if (!found && e.id === obj.id) {
      found = true;
      return obj;
    } else {
      return e;
    }
  });
  if (!found) {
    result.push(obj);
  }
  return result;
}

当然,如果阵列很小并且您知道这是标准情况,那么它并不重要。

如果你想简明扼要地(在我看来)滥用,运营商:

function myFunc(a, obj) {
  let found = false;
  const result = a.map(e => e.id === obj.id ? (found = true, obj) : e);
  if (!found) {
    result.push(obj);
  }
  return result;
}

答案 2 :(得分:0)

如果经常这样做(插入几千个元素),建立一个哈希表(查找时间为O(1)而不是O(n)来搜索数组可能更好(关于性能) ):

var source = [
  {id: 1, label: "one"},
  {id: 2, label: "two"},
  {id: 3, label: "three"}
];
var hash = new Map(source.map((el,i)=>[el.id,i]));

function substitute(elem){
  var i = hash.get(elem.id);
  if(i !== undefined){
    return source[i] = elem;
  }
  hash.set(elem.id,source.push(elem));
}

In action

答案 3 :(得分:0)

&#13;
&#13;
    
    function myFunc( o )
    {
      let i ;
      if ( (i = source[0].indexOf(o.id)) < 0 )
      {
        source[0].push(o.id) ; source.push(o)
      }
      else
      {
        source[1 + i] = o
      }
      // return JSON.parse(JSON.stringify(source)) // new Array with primitives
      return source  // As reference
    }
    
    var source = [
        [4, 1, 3, 2] // the trick here
      , {id: 4, label: "four"}
      , {id: 1, label: "one"}
      , {id: 3, label: "three"}
      , {id: 2, label: "two"}
    ];
    
    var new_sub = {id: 1, label: "new label for one"};
    var new_add = {id: 6, label: "six new label"};
    
    source = myFunc(new_sub);
    
    console.log("// => source after new sub", source);
    
    source = myFunc(new_add);
    
    console.log("// => source after new add", source);
&#13;
&#13;
&#13;