This question already has answers here:
Add prefix to each array object with javascript
(3 answers)
Closed 4 years ago.
I have an array like below:
var arrItems = [
{id: '1', value: 'table', price: 100},
{id: '2', value: 'chair', price: 200},
{id: '3', value: 'bed', price: 300},
];
How to prefix a string 'AB' in each item's id in the array?
My result array should be :
var arrItems = [
{id: 'AB1', value: 'table', price: 100},
{id: 'AB2', value: 'chair', price: 200},
{id: 'AB3', value: 'bed', price: 300},
];
Can I achieve it using the Javascript in map function?
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
I also used the Spread syntax to copy object of collection and for easy property change.
var arrItems = [
{id: '1', value: 'table', price: 100},
{id: '2', value: 'chair', price: 200},
{id: '3', value: 'bed', price: 300},
];
var result = arrItems.map(i => ({...i, id: 'AB' + i.id }))
console.log(result)
You can loop through the array and change the of each object in that array:
var arrItems = [
{id: '1', value: 'table', price: 100},
{id: '2', value: 'chair', price: 200},
{id: '3', value: 'bed', price: 300},
];
// loop through the array and concatenate 'AB' to the id of each object in that array
arrItems.forEach(function(el) {
el.id = 'AB' + el.id;
});
// just for the demo purpose, we'll log the array in the console
var output = 'Result:\n';
arrItems.forEach(function(el) {
output += 'id: ' + el.id + ', value: ' + el.value + ', price: ' + el.price +'\n';
});
console.log(output);
Hope I pushed you further.
Related
This question already has answers here:
Use a concatenated (dynamic) string as JavaScript object key? [duplicate]
(6 answers)
Is it possible to add dynamically named properties to JavaScript object?
(20 answers)
how to concatenate (variable + object key names) to get the object values in dot notation [duplicate]
(1 answer)
Closed 2 years ago.
I have an array of objects like this:
const data = [
{name: 'Page A', count: 4000},
{name: 'Page B', count: 3000},
{name: 'Page C', count: 2000},
];
I need to add an index number to the count property so the list would look like this:
const wantedArray = [
{name: 'Page A', count1: 4000},
{name: 'Page B', count2: 3000},
{name: 'Page C', count3: 2000},
];
I tried this but got this ts error: Operator '+' cannot be applied to types '{ name: any; count: any; }' and 'number'.ts(2365)
let wantedArray: any = []
data.map((object: any, index) => {
wantedArray.push({
name: object.name,
count+index: start.count,
});
});
What is the best solution to achieve this? Thank you.
Simply assign wantedArray to map of the data array, also use [] to assign values with dynamic key.
const data = [
{name: 'Page A', count: 4000},
{name: 'Page B', count: 3000},
{name: 'Page C', count: 2000},
];
let wantedArray = data.map((obj, index) => {
return {
name: obj.name,
[`count${index+1}`]: obj.count
}
});
console.log(wantedArray)
Use bracket notation - [key] for the dynamic key.
const data = [{
name: 'Page A',
count: 4000
},
{
name: 'Page B',
count: 3000
},
{
name: 'Page C',
count: 2000
},
];
const wantedArray = data.map((obj, index) => ({
name: obj.name,
[`count${index+1}`]: obj.count,
}));
console.log(wantedArray);
Use [variablename] to write inside a variable name.
And since the index starts at 0, we do + 1.
const data = [
{name: 'Page A', count: 4000},
{name: 'Page B', count: 3000},
{name: 'Page C', count: 2000},
];
const result = data.map((n, i) => {
return {
name: n.name,
[`count${i+1}`]: n.count,
}
});
console.log(result);
Or if you want to push it into a new array.
const data = [
{name: 'Page A', count: 4000},
{name: 'Page B', count: 3000},
{name: 'Page C', count: 2000},
];
let wantedArray = [];
data.forEach((object, index) => {
return wantedArray.push({
name: object.name,
[`count${index+1}`]: object.count,
});
});
console.log(wantedArray);
I need to get the expectedOutput array, which consists of the objects with the higher amount number. Thanks in advance.
let arr1 = [{name: 'Almendras', amount: 0},{name: 'Nueces', amount: 0}, {name: 'Chocolate', amount: 0}];
let arr2 = [{name: 'Almendras', amount: 2}];
let expectedOutput = [{name: 'Almendras', amount: 2}, {name: 'Nueces', amount: 0}, {name: 'Chocolate', amount: 0}];
Im tried by this way:
console.log(arr2.filter(x => x.amount > arr1[x].amount));
Since the example you gave uses the same index in both arrays, you could map through the first array and index compare the second array and return one or the other:
var res = arr1.map((v, index) => v.amount > arr2[index].amount ? v : arr2[index]);
If either array can be larger than the other you could find the larger array, loop through it and compare it with the smaller one and add the objects to a new array until you reach the end, and then add the remaining objects from the larger array.
You can use Array#map, which provides the index as the second argument to the callback, and use a ternary operator the compare the element at the index in both arrays.
let arr1 = [{name: 'Almendras', amount: 0},{name: 'Nueces', amount: 0}, {name: 'Chocolate', amount: 0}];
let arr2 = [{name: 'Almendras', amount: 2}, {name: 'Nueces', amount: 0}, {name: 'Chocolate', amount: 1}];
let res = arr1.map((curr,idx)=>curr.amount > arr2[idx].amount?curr:arr2[idx]);
console.log(res);
If you know that both arrays are sorted according to the inner object name key, then the other answers which compare indices are probably the best method. However, if you know that the arrays could be unsorted, here is a potential solution.
Note: If you are dealing with arrays of varying sizes, you would have to filter or iterate through both arrays.
let arr1 = [{name: 'Almendras', amount: 0}, {name: 'Nueces', amount: 0}, {name: 'Chocolate', amount: 0}];
let arr2 = [{name: 'Almendras', amount: 2}, {name: 'Chocolate', amount: 1}, {name: 'Nueces', amount: 0}];
let expectedOutput = [{name: 'Almendras', amount: 2}, {name: 'Nueces', amount: 0}, {name: 'Chocolate', amount: 1}];
let actualOutput = arr1.map((ele1) => {
let ele2 = arr2.find((e) => e.name === ele1.name);
if(ele2) {
if(ele2.amount >= ele1.amount) {
return ele2;
}
}
return ele1;
});
console.log("actual: ", actualOutput);
console.log("expected: ", expectedOutput);
I have the following collection of data
[{
id: '1',
date: '2017-01-01',
value: 2
},
{
id: '2',
date: '2017-01-02',
value: 3
},
{
id: '3',
value: 3
},
id: '4',
date: '2017-01-02',
value: 3
}]
I want to delete any object that does not have the 'date' property. In the example above, the object with the id 3 should be deleted.
The finished object should look like this
[{
id: '1',
date: '2017-01-01',
value: 2
},
{
id: '2',
date: '2017-01-02',
value: 3
},
id: '4',
date: '2017-01-02',
value: 3
}]
I tried to find and delete a undefined value with lodash. It does not work. The object looks exactly as it is entering.
_.each(obj, (val) => {
_.remove(val, value => value['XXX-BUDAT'] === undefined);
});
How can I use lodash for this purpose?
Thanks in advance
You can use .filter(), Object.keys(), and .includes()
let input = [
{ id: '1', date: '2017-01-01', value: 2},
{ id: '2', date: '2017-01-02', value: 3},
{ id: '3', value: 3 },
{ id: '4', date: '2017-01-02', value: 3 }
]
let output = input.filter(obj => Object.keys(obj).includes("date"));
console.log(output);
You can filter the array based on that property like this:
const initial = [{
id: '1',
date: '2017-01-01',
value: 2
},
{
id: '2',
date: '2017-01-02',
value: 3
},
{
id: '3',
value: 3
}, { // this left curly brace was missing!, check that out
id: '4',
date: '2017-01-02',
value: 3
}
];
const finalR = initial.filter((obj) => obj.hasOwnProperty('date') && !!obj.date);
console.log(finalR);
You can use Array#filter and Object#hasOwnProperty to do so:
var newArray = oldArray.filter(function(obj) {
return obj.hasOwnProperty("date");
});
Which can be shortened out using an arrow function:
var newArray = oldArray.filter(obj => obj.hasOwnProperty("date"));
Lodash solution:
var newArray = _.filter(oldArray, obj => _.has(obj, "date"));
Example:
var oldArray = [{id: '1', date: '2017-01-01', value: 2 }, { id: '2', date: '2017-01-02', value: 3 }, { id: '3', value: 3 }, {id: '4', date: '2017-01-02', value: 3}];
var newArray = oldArray.filter(obj => obj.hasOwnProperty("date"));
console.log(newArray);
You can use Array.prototype.filter. In addition, you can use ES6 object assignment destructiring to make it concise:
var data=[{id:'1',date:'2017-01-01',value:2},{id:'2',date:'2017-01-02',value:3},{id:'3',value:3},{id:'4',date:'2017-01-02',value:3}];
var result = data.filter(({date}) => date);
console.log(result)
First of all your array of object is not valid, fix it by wrapping the last object element with preceding curly brace {. See Array.prototype.filter() and Object.prototype.hasOwnProperty() that'll check your current object item has the date key or not? if it has then it'll return that object other wise that item will not return.
var array_of_object = [{
id: '1',
date: '2017-01-01',
value: 2
},
{
id: '2',
date: '2017-01-02',
value: 3
},
{
id: '3',
value: 3
},
{ //missing brace here
id: '4',
date: '2017-01-02',
value: 3
}
];
function filterByValue(item) {
return item.hasOwnProperty('date');
}
var arrByID = array_of_object.filter(filterByValue);
console.log(arrByID);
This is a native javascript solution:
var arr = [
{id: '1', date: '2017-01-01', value: 2},
{id: '2', date: '2017-01-02', value: 3},
{id: '3', value: 3},
{id: '4', date: '2017-01-02', value: 3}
]
for(var i = 0; i < arr.length; i++) {
if(!arr[i].hasOwnProperty("date")) {
arr.splice(i,1);
}
}
console.log(arr);
I have an array of objects:
var obj = [
{name: 'a1', type: 't1', price: 10},
{name: 'a1', type: 't1', price: 10},
{name: 'a2', type: 't2', price: 10},
{name: 'a1', type: 't2', price: 10},
];
I need to get this result:
[
{name: 'a1', type: 't1', price: 20},
{name: 'a1', type: 't2', price: 10},
{name: 'a2', type: 't2', price: 10}
]
I want to sum the item if, and only if, the properties name and type match. Any idea?
You can use reduce to group it into an object. Use Object.values to convert the object into array.
var obj = [
{name: 'a1', type: 't1', price: 10},
{name: 'a1', type: 't1', price: 10},
{name: 'a2', type: 't2', price: 10},
{name: 'a1', type: 't2', price: 10},
];
var result = Object.values(obj.reduce((c, v) => {
let k = v.name + '-' + v.type;
c[k] = c[k] || {...v, price: 0};
c[k].price += v.price;
return c;
}, {}));
console.log(result);
You could reduce into a Map and turn it back into an array:
var obj = [
{name: 'a1', type: 't1', price: 10},
{name: 'a1', type: 't1', price: 10},
{name: 'a2', type: 't2', price: 10},
{name: 'a1', type: 't2', price: 10},
];
const map = obj.reduce((map, { name, type, price }) => {
console.log('iter');
const key = name + '_' + type;
return map.set(key, (map.get(key) || 0) + price);
}, new Map());
const output = [...map.entries()].map(([key, val]) => {
const [name, type] = key.split('_');
return { name, type, price: val };
});
console.log(output);
You can try following (sum and sort by name and type)
var obj = [
{name: 'a1', type: 't1', price: 10},
{name: 'a1', type: 't1', price: 10},
{name: 'a2', type: 't2', price: 10},
{name: 'a1', type: 't2', price: 10},
];
// First create the result object where sum of price is done
var result = obj.reduce((a,c) => {
if(a[c.name + "_" + c.type]) {
a[c.name + "_" + c.type].price += c.price;
} else {
a[c.name + "_" + c.type] = c;
}
return a;
}, {});
// Get the values in an array
result = Object.values(result);
// Sort the array by name and then type
result.sort((a,b) => {
if(a.name === b.name) return a.type.localeCompare(b.type);
return a.name.localeCompare(b.name);
});
console.log(result);
You can use of Array.reduce to build up a new array considering your requirements.
const obj = [{
name: 'a1',
type: 't1',
price: 10,
},
{
name: 'a1',
type: 't1',
price: 10,
},
{
name: 'a2',
type: 't2',
price: 10,
},
{
name: 'a1',
type: 't2',
price: 10,
},
].reduce((tmp, x) => {
// Look if there is already a matching item in tmp
const findItem = tmp.find(y => y.name === x.name && y.type === x.type);
// It's not inside
if (!findItem) {
tmp.push(x);
return tmp;
}
// it is inside
findItem.price += x.price;
return tmp;
}, []);
console.log(obj);
Apologies in advance if this has been asked, I've found similar questions but not quite what I've needed.
Basically I have a huge array of objects, simplified it looks like this:
var objects = [
{age: '32', id: '2'},
{age: '56', id: '1'},
{age: '23', id: '2'},
{age: '45', id: '2'},
{age: '48', id: '2'},
{age: '67', id: '1'},
{age: '36', id: '2'},
{age: '45', id: '1'},
]
I need to go through all objects and look at the id, if the id is 2, I need to start counting how many times 2 appears in sequence before the sequence is interrupt by another id(1 in the example).
So in the example above the result would be:
(in the format "times in a row": "count")
one time: 2
three times: 1
var objects = [
{age: '32', id: '2'},
{age: '56', id: '1'},
{age: '23', id: '2'},
{age: '45', id: '2'},
{age: '48', id: '2'},
{age: '67', id: '1'},
{age: '36', id: '2'},
{age: '45', id: '1'}
];
function getStats(arr, id) {
var hash = {}; // the count object
var count = 0; // the counter that count how many occurences that happen after each other
for(var i = 0; i < arr.length; i++) { // loop through the array
if(arr[i].id == id) { // if this element have the id then increment the count
count++;
}
else if(count) { // if not, if count is bigger than 0 then increment the count inside the hash object
hash[count] = hash[count] || 0; // if the hash object doesn't have a counter for the current count, then create one
hash[count]++; // increment that counter
count = 0; // reinitialize the counter back to 0
}
}
// add the last count if there is one (so if there is element at the end we won't skip them)
if(count) {
hash[count] = hash[count] || 0;
hash[count]++;
}
return hash;
}
console.log(getStats(objects, 2)); // you can choose any id (here it will print the result for id = 2)