Add an element to the array or replace it if it has the same identifier

I have this array of objects

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

I need to add an element or replace it if it has the same identifier

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

This code works fine, but is there a better way to do this? You can check my code for this snipp:

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>
Run code
+4
source share
4 answers
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, , ( sources = myFunc(...), sources ).

: ( )

function myFunc(obj) {
  for (var i = 0; i < sources.length && sources[i].id !== obj.id; i++) // stop when reaching the end of the array or when we find an object with the same id
    ;                                                                  // empty loop (just using it to find the index)
  sources[i] = obj;                                                    // i will be either the index of the found object (so it will be replaced by obj) or sources.length (so obj will be added to the array)
}
+1

( findIndex, concat map), . :

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;
}
+1

If you often do this (insert a few thousand elements), it might be better (relative to performance) to create a hash table (which has an O (1) lookup time instead of O (n) to search for an array):

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

0
source

    
    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);
Run code
0
source

Source: https://habr.com/ru/post/1682847/


All Articles