2

I have an array of objects which looks like this:

var finishes = [
    {label:'Raw Steel'},
    {label:'Antique Pewter'},
    {label:'Barn Red'},
    {label:'Brushed Stainless Steel'},
    {label:'Brushed Steel'},
    {label:'Copper Patina'},
    {label:'Dark Bronze'},
    {label:'Distressed White'},
    {label:'Flat Black'},
    {label:'Green Patina'},
    {label:'Oil Rubbed Bronze'},
    {label:'White'},
    {label:'Warehouse Bronze'},
    {label:'Weathered Rust'},
];

var wheelFinishes = finishes;

As you can see I setup another array of objects which is going to have some different attributes then the "seed" array of objects.

So what I want to do is something like:

UPDATE wheelFinishes WHERE label="Barn Red" SET exclusion="Metal Values"

So the value of wheelFinishes would end up as:

var wheelFinishes = [
    {label:'Raw Steel'},
    {label:'Antique Pewter'},
    {label:'Barn Red', exclusion:'Metal Values'},
    {label:'Brushed Stainless Steel'},
    {label:'Brushed Steel'},
    {label:'Copper Patina'},
    {label:'Dark Bronze'},
    {label:'Distressed White'},
    {label:'Flat Black'},
    {label:'Green Patina'},
    {label:'Oil Rubbed Bronze'},
    {label:'White'},
    {label:'Warehouse Bronze'},
    {label:'Weathered Rust'},
];

I'm not sure on the actual syntax to update an array of objects in javascript.

I know underscorejs might have some functions that make this type of thing easier, so i'm open to a solution in underscorejs if that's even possible?

Jordash
  • 2,926
  • 8
  • 38
  • 77
  • 2
    This can be worked out with `.find()` https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find – Robert Aug 06 '16 at 19:55

5 Answers5

3

using Array.prototype.map would be one (of multiple) possible solution:

var wheelFinishes = [
    {label:'Raw Steel'},
    {label:'Antique Pewter'},
    {label:'Barn Red'},
    {label:'Brushed Stainless Steel'},
    {label:'Brushed Steel'},
    {label:'Copper Patina'},
    {label:'Dark Bronze'},
    {label:'Distressed White'},
    {label:'Flat Black'},
    {label:'Green Patina'},
    {label:'Oil Rubbed Bronze'},
    {label:'White'},
    {label:'Warehouse Bronze'},
    {label:'Weathered Rust'},
];

//extend all objects having a specific label
updatedFinishes = wheelFinishes.map(function(obj) {
  if(obj.label === 'Barn Red') {
    obj.exclusion = 'Metal Values';
  }
  return obj;
});
  
//test
updatedFinishes.forEach(function(obj) {
  console.log(obj);
})
MattDiMu
  • 4,873
  • 1
  • 19
  • 29
2

Iterate through the array, and append a property.

Use a function update. I accepts a set of label elements needs to be modified. Under each set of labels, there is another set to append.

var finishes = [{
  label: 'Raw Steel'
}, {
  label: 'Antique Pewter'
}, {
  label: 'Barn Red'
}, {
  label: 'Brushed Stainless Steel'
}, {
  label: 'Brushed Steel'
}, {
  label: 'Copper Patina'
}, {
  label: 'Dark Bronze'
}, {
  label: 'Distressed White'
}, {
  label: 'Flat Black'
}, {
  label: 'Green Patina'
}, {
  label: 'Oil Rubbed Bronze'
}, {
  label: 'White'
}, {
  label: 'Warehouse Bronze'
}, {
  label: 'Weathered Rust'
}, ];

function update(arr) {
  var i, len, len2, len3, elem, j, k, key, value;
  for (i = 0, len = arr.length; i < len; i += 1) {
    elem = arr[i];
    for (j = 0, len2 = finishes.length; j < len2; j += 1) {
      if (finishes[j].label === elem.label) {
        for (k = 0, len3 = elem.set.length; k < len3; k += 1) {
          key = elem.set[k].key;
          value = elem.set[k].value;
          finishes[j][key] = value;
        }
      }
    }
  }
  return finishes;
}

console.log(update([{
  label: 'Barn Red',
  set: [{
    key: 'exclusion1',
    value: 'Metal Values1'
  }, {
    key: 'exclusion2',
    value: 'Metal Values2'
  }]
}]));
Ayan
  • 2,300
  • 1
  • 13
  • 28
  • I'm trying to write a function that can do this really quickly for a variety of different applications – Jordash Aug 06 '16 at 19:59
  • Yeah was updating that only, check... we can make it more generalise... – Ayan Aug 06 '16 at 20:01
  • @Jordash Now check, its fully generalised now. Feed it dynamically. Check the usage of update function. You ask find me these labels, under each set of label, set these sets of properties. – Ayan Aug 06 '16 at 20:18
  • Nicely done. Though, I think this is incredibly complex. – Robert Aug 06 '16 at 21:03
2

Note that, unlike map(), this only works for the first item with {label: 'Barn Red'} in an array.

As suggested by @RobertRocha:

var wheelFinishes = finishes.slice();
wheelFinishes.find(function (finish) {
  return finish.label === 'Barn Red';
}).exclusion = 'Metal Values';

This copies the array using slice, then finds the item with .label === 'Barn Red'.


In ES6:

const wheelFinishes = finishes.slice();
wheelFinishes
  .find(finish => finish.label === 'Barn Red')
  .exclusion = 'Metal Values';
Community
  • 1
  • 1
gcampbell
  • 1,252
  • 15
  • 13
2

To make it as compatible with your concept of

UPDATE wheelFinishes WHERE label="Barn Red" SET exclusion="Metal Values"

and to make it as loosely coupled/independent as possible, here is a function that might help you:

    var finishes = [
    {label:'Raw Steel'},
    {label:'Antique Pewter'},
    {label:'Barn Red'},
    {label:'Brushed Stainless Steel'},
    {label:'Brushed Steel'},
    {label:'Copper Patina'},
    {label:'Dark Bronze'},
    {label:'Distressed White'},
    {label:'Flat Black'},
    {label:'Green Patina'},
    {label:'Oil Rubbed Bronze'},
    {label:'White'},
    {label:'Warehouse Bronze'},
    {label:'Weathered Rust'},
    ];

    var wheelFinishes = finishes;

    function update(table, searchItem, setValue) {
        function search(table) {
            if(table.label == searchItem) {
                table.exclusion = setValue;
            }
        }

        table.find(search);
    }

    update(wheelFinishes, 'Barn Red', 'Metal Values');

    console.log(wheelFinishes[2]);

Result: Object {label: "Barn Red", exclusion: "Metal Values"}

Robert
  • 10,126
  • 19
  • 78
  • 130
1

You could use e.g. a regular forEach for this:

var finishes = [
    {label:'Raw Steel'},
    {label:'Antique Pewter'},
    {label:'Barn Red'},
    {label:'Brushed Stainless Steel'},
    {label:'Brushed Steel'},
    {label:'Copper Patina'},
    {label:'Dark Bronze'},
    {label:'Distressed White'},
    {label:'Flat Black'},
    {label:'Green Patina'},
    {label:'Oil Rubbed Bronze'},
    {label:'White'},
    {label:'Warehouse Bronze'},
    {label:'Weathered Rust'},
];
  
finishes.forEach(function(f) {
  if(f.label === 'Barn Red') {
    f.exclusion = 'Metal Values';
  }  
});
  
console.log(finishes);
Tholle
  • 108,070
  • 19
  • 198
  • 189