0

I'm wondering if something like this is possible - an extend that looks at an array of objects

Lets say I have :

 myObj = [
    {"name" : "one", "test" : ["1","2"]},
    {"name" : "two", "test" : ["1","2"]}
   ]

And I'm trying to extend into that

 {"name" : "one" , "test" : ["1","3"]}

So the result would be -

 myObj = [
    {"name" : "one", "test" : ["1","2", "3"]},
    {"name" : "two", "test" : ["1","2"]}
   ]

And this would be like extend in that if there is no object there it would just create one. IS something like this possible? Thanks!

3
  • With vanilla javascript? Or with a library? Commented Mar 6, 2015 at 16:02
  • Why does the union of ["1","2"] and ["1","3"] become ["1","2","3"]? How should the final order be in an arbitrary case? Commented Mar 6, 2015 at 16:06
  • @jamiec, either or, I have underscore in right now, but i'm not picky Commented Mar 6, 2015 at 16:06

2 Answers 2

2

It looks like you want something like:

function deepSetMerge(base, next) {
  var dataEntry = base.filter(function(it) {
    return it.name === next.name;
  })[0];

  if (dataEntry) {
    var diff = next.test.filter(function(it) {
      return dataEntry.test.indexOf(it) === -1;
    });
    dataEntry.test = dataEntry.test.concat(diff).sort();
  } else {
    base.push(next);
  }
}

var data = [{
  "name": "one",
  "test": ["1", "2"]
}, {
  "name": "two",
  "test": ["1", "2"]
}];

var add = {
  "name": "one",
  "test": ["1", "3"]
};

var obj = {
  "name": "totally-unique",
  "test": [1, 2, "nine", 17.0]
};

deepSetMerge(data, add);
deepSetMerge(data, obj);

document.getElementById('results').textContent = JSON.stringify(data);
<pre id="results"></pre>

This function works by finding the existing entry, by name, if one exists. If not, we just push the object to be merged in as a new entry.

If the entry does exist, find the difference between the two sets of items, then concatenate them onto the end of the existing array (and sort the results).

This is pretty specific to your data structure and not the most flexible solution in the world, but hopefully shows the algorithm well.

Sign up to request clarification or add additional context in comments.

7 Comments

Ah, awesome! does this handle a use case where say I try to add a completely new object? like if I tried to add {name : 5, test [ 4,6 ] }? Thanks!
@ajmajmajma yep, added an example of that.
@ssube oh you and I had the same thought only looks like you implemented it better with filter and concat. Good job!
I'm getting an undefined is not a function on, var dataEntry = base.filter(function(it) { . I have no idea why, the objects I'm passing look fine. Any idea? Thanks again!
@ajmajmajma What implementation are you using? filter may not be available in all of them, although you can replace it with a loop very easily.
|
1

As a universal extend implementation this would be quite tricky and costly. It is why deep dives are usually avoided. It is better to know your data model and work with it that way.

Using your example I would establish some assumptions on the data model in question:

  1. Our object will have a name property which is unique and can be searched for.
  2. The value of the test property is an array (makes this easier but it could be an object that you use a typical extend implementation on.

In which case you could approach it like this:

var myObj = [
  {name: 'one', test: ['1', '2']},
  {name: 'two', test: ['1', '2']}
];

function extendTestValue(data, value) {
  var names = data.map(function(item) {
    return item.name;
  });
  var index = names.indexOf(value.name);
  if (index < 0) {
    data.push(value);
  } else {
    value.test.forEach(function(item) {
      if (data[index].test.indexOf(item) < 0) {
        data[index].test.push(item);
      }
    });
  }
  return data;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.