I have an array of objects like so:
array = [{item_name: "necklace", quantity: "2"},
{item_name: "necklace", quantity: "4"},
{item_name: "bracelet", quantity: "5"}];
I would like to merge these objects in the array to end up with an array that looks like this:
array = [{item_name: "necklace", quantity: "6"},
{item_name: "bracelet", quantity: "5"}];
I'm unsure how to begin to tackle this. I have tried concat and merge but these override the values. Do I need to map?
Any help would be greatly appreciated!
You can just simply loop over the array and push the values into a new array, checking first to see if the item_name is already in there.
An easier way to check if the object is already in the new array is to create an object with the item_name and its position in the new array. Otherwise, you'd need to loop over the new array each time to check.
Try this:
function merge_data(array){
var new_array = [],
item_map = {};
// Loop over the array
array.forEach(function(v){
var item = v.item_name;
// The object is not already in the new array
if(item_map[item] === undefined){
// Push the object and save its index
item_map[item] = new_array.length;
// WARNING: This pushes a *reference* to `v` into the new array
// which means when I update `new_array[pos]`, it'll also update
// this object in the *original* array
//new_array.push(v);
new_array.push({
item_name: item,
quantity: v.quantity
});
}
// The object is already in the new array
else{
// Get its index and update the quantity
var pos = item_map[item],
// quantity is a string, we need to make it into an int
quantity = parseInt(new_array[pos].quantity, 10);
new_array[pos].quantity = quantity + parseInt(v.quantity, 10);
}
});
return new_array;
}
// Now `array` will have the merged data
array = merge_data(array);
console.log(array);
Related
I want to Update array of objects by another array of objects.
I have 2 array of objects like this:
const array = [
{id:'a',html:'',user:''},
{id:'b',html:'',user:''},
{id:'c',html:'',user:''},
];
const array_two = [
{id:'a',html:'',user:''},
{id:'b',html:'',user:''},
{id:'c',html:'',user:''},
{id:'d',html:'<p>Hello World</p>',user:'TEST USER'},
{id:'e',html:'<p>Hello World TWO</p>',user:'TEST USER TWO'},
];
and I want updateenter code here array by anotherArray
So my desired output is:
[
{id:'a',html:'<p>Hello World</p>',user:'TEST USER'},
{id:'b',html:'<p>Hello World TWO</p>',user:'TEST USER TWO'},
{id:'c',html:'',user:''},
];
Assuming (unlike your example) that you want objects with matching ids to update, here's how I would implement this:
Build an object byId mapping ids to corresponding object.
Loop through the updates and apply Object.assign to update the objects in-place, using byId to know which object to update.
const byId = {};
array.forEach((obj) => byId[obj.id] = obj);
array_two.forEach((obj) => {
if (!Object.hasOwnProperty(byId, obj.id)) {
// Create new object if id doesn't already exist.
byId[obj.id] = obj;
array.push(obj);
} else {
// Update existing object.
Object.assign(byId[obj.id], obj);
}
});
I have an array of objects:
boxes= [{"itemsId":19,"quantity":0},{"itemsId":1053,"quantity":1},{"itemsId":1056,"quantity":1}];
How to pair values of objects from array?
Here's what I'd like boxes to look like:
boxes= [{"itemsId":quantity},{"itemsId":quantity},{"itemsId":quantity}];
ie.
boxes= [{"19":0},{"1053":1},{"1056":1}];
You can try with Array.prototype.map():
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
In each iteration set the value of itemsId as the key and the value of quantity as the value for that key.
var boxes= [{"itemsId":19,"quantity":0},{"itemsId":1053,"quantity":1},{"itemsId":1056,"quantity":1}];
boxes = boxes.map(i => ({[i.itemsId]:i.quantity}));
console.log(boxes);
You can use map to return an array and inside the callback return an object.Use square notation to create the object key. Since object key is unique the new value will overwrite old value inside an object
let boxes = [{
"itemsId": 19,
"quantity": 0
}, {
"itemsId": 1053,
"quantity": 1
}, {
"itemsId": 1056,
"quantity": 1
}];
let newData = boxes.map(function(elem) {
return {
[elem.itemsId]: elem.quantity
}
});
console.log(newData)
Using map()
var boxes = [{"itemsId":19,"quantity":0},{"itemsId":1053,"quantity":1},{"itemsId":1056,"quantity":1}];
var result = boxes.map(({itemsId, quantity}) => ({[itemsId]: quantity}))
console.log(result)
I have array, created from json:
var array = [{"name":"name1","group":"group1","id":"123", ...},
{"name":"name2","group":"group2","id":"456", ...},
{"name":"name3","group":"group1","id":"789", ...}];
After I get another array:
var array1 = [{"name":"name1","group":"group1","id":"123", ...},
{"name":"name4","group":"group1","id":"987", ...}]
I need to push items from second array into first, but how can I check if first array contains objects from second array?
Each object in array contain more property and some of them are created dynamically so I can't check for example by indexOf(). All solutions that I found works only with simple objects like Int. It will be great if I could check by property "id" for example.
Use find first
var newObj = {"name":"name2","group":"group2","id":"456"};
var value = array.find( s => s.id == newObj.id );
Now push if the value is not found
if ( !value )
{
array.push( newObj )
}
(More generic)you can do this one line using following (which will add all object which is not in array).
array.concat(array1.filter(x=>!array.find(s=>s.id==x.id)));
var array = [{"name":"name1","group":"group1","id":"123"},
{"name":"name2","group":"group2","id":"456" },
{"name":"name3","group":"group1","id":"789"}];
var array1 = [{"name":"name1","group":"group1","id":"123"},
{"name":"name4","group":"group1","id":"987"}];
array=array.concat(array1.filter(x=>!array.find(s=>s.id==x.id)));
console.log(array);
How to create new array from slicing the existing array by it's key?
for example my input is :
var array = [{"one":"1"},{"one":"01"},{"one":"001"},{"one":"0001"},{"one":"00001"},
{"two":"2"},{"two":"02"},{"two":"002"},{"two":"0002"},{"two":"00002"},
{"three":"3"},{"three":"03"},{"three":"003"},{"three":"0003"},{"three":"00003"},
{"four":"4"},{"four":"04"},{"four":"004"},{"four":"0004"},{"four":"00004"},
{"five":"5"},{"five":"05"},{"five":"005"},{"five":"0005"},{"five":"00005"} ];
my output should be :
var outPutArray = [
{"one" : ["1","01","001","0001","00001"]},
{"two":["2","02","002","0002","00002"]},
{"three":["3","03","003","0003","00003"]},
{"four":["4","04","004","0004","00004"]},
{"five":["5","05","005","0005","00005"]}
]
is there any short and easy way to achieve this in javascript?
You can first create array and then use forEach() loop to add to that array and use thisArg param to check if object with same key already exists.
var array = [{"one":"1","abc":"xyz"},{"one":"01"},{"one":"001"},{"one":"0001"},{"one":"00001"},{"two":"2"},{"two":"02"},{"two":"002"},{"two":"0002"},{"two":"00002"},{"three":"3"},{"three":"03"},{"three":"003"},{"three":"0003"},{"three":"00003"},{"four":"4"},{"four":"04"},{"four":"004"},{"four":"0004"},{"four":"00004"},{"five":"5"},{"five":"05"},{"five":"005"},{"five":"0005"},{"five":"00005","abc":"xya"} ];
var result = [];
array.forEach(function(e) {
var that = this;
Object.keys(e).forEach(function(key) {
if(!that[key]) that[key] = {[key]: []}, result.push(that[key])
that[key][key].push(e[key])
})
}, {})
console.log(result);
var outputArray=[array.reduce((obj,el)=>(Object.keys(el).forEach(key=>(obj[key]=obj[key]||[]).push(el[key])),obj),{})];
Reduce the Array to an Object,trough putting each Arrays object key to the Object as an Array that contains the value.
http://jsbin.com/leluyaseso/edit?console
I need to group item having same name property and increase their number. I try to assign to new array and check existed item by key. It works fine when I use this solution in PHP, but in JavaScript it doesn't.
I have searched some similar questions, but I don't know why it doesn't work.
var orgArr = [
{name: 'abc', number: 3},
{name: 'xyz', number: 2},
{name: 'abc', number: 5}
];
var result = []; //work if result = {};
for (var i = 0; i < orgArr.length; i++) {
if (!result[orgArr[i].name]) {
result[orgArr[i].name] = orgArr[i]; //assign new
} else {
result[orgArr[i].name].number += orgArr[i].number; //increase number if name exist in result array
}
}
alert(JSON.stringify(result)); //expect array 2 item but it's empty array
console.log(result); //Will have result 2 item when I view console window
var orgArr = [
{name: 'abc', number: 3},
{name: 'xyz', number: 2},
{name: 'abc', number: 5}
];
var result = []; //work if result = {};
var tempArray = []; // used to store unique name to prevent complex loop
orgArr.forEach(function(item){
if($.inArray(item.name, tempArray)< 0){// unique name
result.push(item);
tempArray.push(item.name);
}
else{
var indexNew = $.inArray(item.name, tempArray);
result[indexNew].number += item.number;
}
});
alert(JSON.stringify(result)); //expect array 2 item but it's empty array
console.log(result); //Will have result 2 item when I view console window
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
E/ My previous answer was incorrect.
Well.. yes...
[] designates an array. An array holds everything by integer values. You're trying to feed it a string value (orgArr[x].name) and since its just an array, it discards it as a bad call.
{} is an object. Objects can have string indexes.
var result = []; //work if result = {};
Why can't result be {}?
if you want it to work, make result = {} not []
an array is not a key value store. It still will take key values, and will store them on the array object. But when stringify encounters your array, it determines it is an array and then trys to iterate the array, and your array appears empty. so you get nothing in your output.
You get empty array it's because by default JSON.stringify failed to convert your array to json string.
By default JSON.stringify converts int-based index array to json string but you are using orgArr[i].name which is a string as array index that the cause alert() show empty array.
Can you explain why would you want to convert json array to an array with string index. It's always better to use json array if you want a string as key/index.
For more information about JSON.stringify