I have an array of objects. Each object has an amount and value property. If an object has the same amount value I would like to add that value to that object.
Here's an example array:
const array = [
{
"key": 1,
"amount": 11,
"value": "were"
},
{
"key": 2,
"amount": 6,
"value": "locomotives"
},
{
"key": 3,
"amount": 5,
"value": "They"
},
{
"key": 4,
"amount": 5,
"value": "with"
},
{
"key": 5,
"amount": 4,
"value": "used"
}
]
I would like to transform this to resemble this:
const array = [
{
"key": 1,
"amount": 11,
"value": "were"
},
{
"key": 2,
"amount": 6,
"value": "locomotives"
},
{
"key": 3,
"amount": 5,
"value": "They, width"
},
{
"key": 5,
"amount": 4,
"value": "used"
}
]
I've tried reduce and map but I can't seem to get it to join,
I think should work with .reduce():
const array = [
{
"key": 1,
"amount": 11,
"value": "were"
},
{
"key": 2,
"amount": 6,
"value": "locomotives"
},
{
"key": 3,
"amount": 5,
"value": "They"
},
{
"key": 4,
"amount": 5,
"value": "with"
},
{
"key": 5,
"amount": 4,
"value": "used"
}
];
const result = array.reduce((a, c) => {
const found = a.find(e => e.amount === c.amount);
if (found) found.value = `${found.value}, ${c.value}`;
return found ? a : a.concat(c);
}, []);
console.log(result);
I hope that helps!
You can use .reduce() with an ES6 Map by indexing by the amount value. If an object's amount value already exists within the map, you can update its value to include the current objects value. If the amount value isn't in the map, you can set it as a key and the current object as the value. Lastly, you can use Array.from() to get an array of object values from the iterator returned by .values()
const array = [ { "key": 1, "amount": 11, "value": "were" }, { "key": 2, "amount": 6, "value": "locomotives" }, { "key": 3, "amount": 5, "value": "They" }, { "key": 4, "amount": 5, "value": "with" }, { "key": 5, "amount": 4, "value": "used" } ];
const res = Array.from(array.reduce((m, o) => {
const curr = m.get(o.amount);
return m.set(o.amount, curr && {...curr, value: `${curr.value}, ${o.value}`} || o);
}, new Map).values());
console.log(res);
mine..
const array1 =
[ { key: 1, amount: 11, value: "were" }
, { key: 2, amount: 6, value: "locomotives" }
, { key: 3, amount: 5, value: "They" }
, { key: 4, amount: 5, value: "with" }
, { key: 5, amount: 4, value: "used" }
]
const array2 = array1.reduce((a,c)=>
{
let same = a.find(e=>e.amount===c.amount)
if (same) same.value += ', '+c.value
else a.push(c)
return a
},[])
console.log( array2 )
In each iteration of reduce method, we can add value if there is an already added value:
const result = array.reduce((a, c) => {
a[c.amount] = a[c.amount] || c;
if ((Object.keys(a).includes(c.amount.toString())) && (a[c.amount].value!= c.value))
a[c.amount].value += ', ' + c.value;
return a;
}, {});
An example:
const array = [
{
"key": 1,
"amount": 11,
"value": "were"
},
{
"key": 2,
"amount": 6,
"value": "locomotives"
},
{
"key": 3,
"amount": 5,
"value": "They"
},
{
"key": 4,
"amount": 5,
"value": "with"
},
{
"key": 5,
"amount": 4,
"value": "used"
}
];
const result = array.reduce((a, c) => {
a[c.amount] = a[c.amount] || c;
if ((Object.keys(a).includes(c.amount.toString())) && (a[c.amount].value!= c.value))
a[c.amount].value += ', ' + c.value;
return a;
}, {});
console.log(result);
Use forEach loop and build an object. If the amount key already exist then append the value string.
const update = data => {
const res = {};
data.forEach(item => {
res[item.amount] =
item.amount in res
? {
...res[item.amount],
value: `${res[item.amount].value}, ${item.value}`
}
: { ...item };
});
return Object.values(res);
};
const array = [
{
key: 1,
amount: 11,
value: "were"
},
{
key: 2,
amount: 6,
value: "locomotives"
},
{
key: 3,
amount: 5,
value: "They"
},
{
key: 4,
amount: 5,
value: "with"
},
{
key: 5,
amount: 4,
value: "used"
}
];
console.log(update(array));
Related
How to find name using id. means iterate object. create a function const searchName =()=>{}
suppose if pass 3 in function so I'd want to show .... what the name of user like this
const data = [{
"service": [
"BUSINESS",
"LEGAL",
"FINANCE",
"ADVERTISEMENT"
],
"service1": [
{ "id": 1, "name": "a" },
{ "id": 2, "name": "b" },
{ "id": 3, "name": "c" },
{ "id": 4, "name": "d" },
],
"service2": [
{ "id": 5, "name": "e" },
{ "id": 6, "name": "f" },
{ "id": 7, "name": "g" },
{ "id": 8, "name": "h" },
],
"service3": [
{ "id": 9, "name": "i" },
{ "id": 10, "name": "j" },
{ "id": 11, "name": "k" },
{ "id": 12, "name": "l" },
],
"service4": [
{ "id": 13, "name": "m" },
{ "id": 14, "name": "n" },
{ "id": 15, "name": "o" },
{ "id": 16, "name": "p" },
],
}
]
suppose user pass 3 so I want to return { "id": 3, "name": "c" } like this.
I'm trying to iterate this and find the name of the user by id but I didn't understand this iteration so I need your help.
check this code.... Enter any id number
const data = [{
"service": [
"BUSINESS",
"LEGAL",
"FINANCE",
"ADVERTISEMENT"
],
"service1": [
{ "id": 1, "name": "a" },
{ "id": 2, "name": "b" },
{ "id": 3, "name": "c" },
{ "id": 4, "name": "d" },
],
"service2": [
{ "id": 5, "name": "e" },
{ "id": 6, "name": "f" },
{ "id": 7, "name": "g" },
{ "id": 8, "name": "h" },
],
"service3": [
{ "id": 9, "name": "i" },
{ "id": 10, "name": "j" },
{ "id": 11, "name": "k" },
{ "id": 12, "name": "l" },
],
"service4": [
{ "id": 13, "name": "m" },
{ "id": 14, "name": "n" },
{ "id": 15, "name": "o" },
{ "id": 16, "name": "p" },
],
}]
var itemobj = ''
const searchName =(val)=>{
console.log('searchname')
data.map((item)=>{
let obj = Object.keys(item)
obj.map((data)=>{
let inrdata = item[data]
inrdata.map((initem)=>{
let lastdata = initem.id===val?itemobj=initem:null
})
})
})
}
searchName(3)
console.log(itemobj)
function searchName(id) {
let result = null;
for (const [key, value] of Object.entries(data)) {
if (key === "service") continue
result = value.filter(obj => {
return obj.id === id
})
if (result) break
}
return result ? result[0] : null
}
I iterate through keys, I just skip "service" one since it's not revelant.
Then, I filter the "serviceN" array, it will return an array of object (only one if found, empty array if not found).
If it's found, we stop iterating.
Then we return either the first (and logically only element) or null if not found
You could use a combination of flat and find to get get the user by id
function searchName(id) {
return data
.flatMap((item) => Object.values(item))
.flat()
.find((user) => user.id === id);
}
const result = searchName(3); // { id: 3, name: 'c' } | undefined
i have 2 array of objects and I need to sort one array of object depends on another array key value
array1: [
{
group: 'GROUP1',
sort_order: 1,
},
{
group: 'GROUP2',
sort_order: 2,
},
{
group: 'GROUP3',
sort_order: 3,
}
],
array2: {
'GROUP3' : [
{
"price": 10,
"amount": 2,
},
{
"price": 45,
"amount": 7,
},
],
'GROUP2' : [
{
"price": 10,
"amount": 2,
},
{
"price": 45,
"amount": 7,
},
],
'GROUP1' : [
{
"price": 10,
"amount": 2,
},
{
"price": 45,
"amount": 7,
},
]
}
No I need to order my array2 indexes based on array1 "sort_order".
i am expecting the order of array2 something like GROUP1, GROUP2, GROUP3
Thanks in advance
let sorted = Object.entries(array2).sort(([groupA], [groupB]) =>
array1.find(e => e.group === groupA).sort_order -
array1.find(e => e.group === groupB).sort_order)
would give you
[
[
"GROUP1",
[
{
"price": 10,
"amount": 2
},
{
"price": 45,
"amount": 7
}
]
],
[
"GROUP2",
[
{
"price": 10,
"amount": 2
},
{
"price": 45,
"amount": 7
}
]
],
...
As i understood you need to sort second array using info from first one. I prefer to keep original array and do sort in computed property.
Example:
const app = new Vue({
el:'#app',
data: () => ({
array1: [
{
group: 'GROUP1',
sort_order: 1,
},
{
group: 'GROUP2',
sort_order: 2,
},
{
group: 'GROUP3',
sort_order: 3,
},
],
array2: {
'GROUP3' : [
{
"price": 10,
"amount": 2,
},
{
"price": 45,
"amount": 7,
},
],
'GROUP2' : [
{
"price": 10,
"amount": 2,
},
{
"price": 45,
"amount": 7,
},
],
'GROUP1' : [
{
"price": 10,
"amount": 2,
},
{
"price": 45,
"amount": 7,
},
],
},
}),
mounted() {
setTimeout(() => {
console.log(this.sortedArray2);
}, 1000);
},
computed: {
sortedArray2() {
const arr2 = { ...this.array2 };
this.array1.map(item1 => {
arr2[item1.group] = arr2[item1.group].sort((a, b) => {
switch(item1.sort_order) {
case 1: {
return a.price > b.price ? 1 : -1;
}
case 2: {
return a.price < b.price ? 1 : -1;
}
default: {
return a.amount < b.amount ? 1 : -1;
}
}
});
});
return arr2;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
</div>
I have the following array
[
{
"id": 1,
"name": "Ruan Duarte",
"idade": 11,
"work": {
"id": 2
}
},
{
"id": 2,
"name": "Raul Dias",
"idade": 13
},
{
"id": 7,
"name": "Caio",
"idade": 60,
"work": {
"id": 4
}
},
{
"id": 3,
"name": "Felipe Lima",
"idade": 55
},
{
"id": 4,
"name": "Camila",
"idade": 25,
"work": {
"id": 3
}
}
]
I have an array in this format, where the work.id field in some corners is null.
I try to do the ordering as follows ...
array.sort((a, b) => {
return (
a.work.id - b.work.id
)
})
However, I get an error for the non-existence of the id
You could take optional chaining operator ?. with the properties and the Nullish coalescing operator ?? for taking a default value which respects zero.
By taking Number.MAX_VALUE as default value, all objects with missing nested objects are sorted to bottom.
const
data = [{ id: 1, name: "Ruan Duarte", idade: 11, work: { id: 2 } }, { id: 2, name: "Raul Dias", idade: 13 }, { id: 7, name: "Caio", idade: 60, work: { id: 4 } }, { id: 3, name: "Felipe Lima", idade: 55 }, { id: 4, name: "Camila", idade: 25, work: { id: 3 } }];
data.sort((a, b) => (a?.work?.id ?? Number.MAX_VALUE) - (b?.work?.id ?? Number.MAX_VALUE));
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
This might help
array.sort((a, b) => {
return (
(a.work != null ? a.work.id : -Infinity) - (b.work != null ? b.work.id : -Infinity)
)
});
If you need to sort by work.id:
const arr = [
{
"id": 1,
"name": "Ruan Duarte",
"idade": 11,
"work": {
"id": 2
}
},
{
"id": 2,
"name": "Raul Dias",
"idade": 13
},
{
"id": 7,
"name": "Caio",
"idade": 60,
"work": {
"id": 4
}
},
{
"id": 3,
"name": "Felipe Lima",
"idade": 55
},
{
"id": 4,
"name": "Camila",
"idade": 25,
"work": {
"id": 3
}
}
]
arr.sort((a, b) => {
if (a.work && b.work) {
return a.work.id > b.work.id ? 1 : - 1
} else if (!a.work && !b.work) {
return a.id > b.id ? 1 : - 1
} else if (!a.work) {
return 1
} else {
return - 1
}
})
output:
[
{
"id": 1,
"name": "Ruan Duarte",
"idade": 11,
"work": {
"id": 2
}
},
{
"id": 4,
"name": "Camila",
"idade": 25,
"work": {
"id": 3
}
},
{
"id": 7,
"name": "Caio",
"idade": 60,
"work": {
"id": 4
}
},
{
"id": 2,
"name": "Raul Dias",
"idade": 13
},
{
"id": 3,
"name": "Felipe Lima",
"idade": 55
}
]
This question already has answers here:
Merge/flatten an array of arrays
(84 answers)
Closed 3 years ago.
I've got array model and I want to use its values array separetaly, since flatMap is not available in my angular application without adding "esnext" to tsconfig.json file I was wondering if it's possible to do the same result without flatMap. Here's my current result:
var model= [
{
"values": [
{
"colId": 1,
"value": 7086083333.333333
},
{
"colId": 2,
"value": null
},
],
"rowId": 0,
},
{
"values": [
{
"colId": 1,
"value": null
},
],
"rowId": 1,
"rowHeader": ""
},
{
"values": [
{
"colId": 1,
"value": null
},
{
"colId": 2,
"value": null
},
],
"rowId": 2,
"rowHeader": ""
}
]
const data = model.flatMap((wm) => wm.values);
console.log(data);
You can use reduce() method to do that.
var model = [{ "values": [{ "colId": 1, "value": 7086083333.333333 }, { "colId": 2, "value": null }, ], "rowId": 0, }, { "values": [{ "colId": 1, "value": null }, ], "rowId": 1, "rowHeader": "" }, { "values": [{ "colId": 1, "value": null }, { "colId": 2, "value": null }, ], "rowId": 2, "rowHeader": "" } ];
const data = model.reduce((arr, currentValue) => {
return arr.concat(currentValue.values);
}, []);
console.log(data);
I'm trying to figure out how to do this in ES6...
I have this array of objects..
const originalData=[
{"investor": "Sue", "value": 5, "investment": "stocks"},
{"investor": "Rob", "value": 15, "investment": "options"},
{"investor": "Sue", "value": 25, "investment": "savings"},
{"investor": "Rob", "value": 15, "investment": "savings"},
{"investor": "Sue", "value": 2, "investment": "stocks"},
{"investor": "Liz", "value": 85, "investment": "options"},
{"investor": "Liz", "value": 16, "investment": "options"}
];
..and this new array of objects where I want to add each person's total value of their investment types (stocks, options, savings)..
const newData = [
{"investor":"Sue", "stocks": 0, "options": 0, "savings": 0},
{"investor":"Rob", "stocks": 0, "options": 0, "savings": 0},
{"investor":"Liz", "stocks": 0, "options": 0, "savings": 0}
];
I loop through originalData and save each property of the "current object" in a let..
for (let obj of originalData) {
let currinvestor = obj.investor;
let currinvestment = obj.investment;
let currvalue = obj.value;
..but here I want to find the obect in newData that has the property = currinvestor (for the "investor" key)
...then add that investment type's (currinvestment) value (currvalue)
}
newData.find(x => x.investor === investor)
And the whole code:
const originalData = [
{ "investor": "Sue", "value": 5, "investment": "stocks" },
{ "investor": "Rob", "value": 15, "investment": "options" },
{ "investor": "Sue", "value": 25, "investment": "savings" },
{ "investor": "Rob", "value": 15, "investment": "savings" },
{ "investor": "Sue", "value": 2, "investment": "stocks" },
{ "investor": "Liz", "value": 85, "investment": "options" },
{ "investor": "Liz", "value": 16, "investment": "options" },
];
const newData = [
{ "investor": "Sue", "stocks": 0, "options": 0, "savings": 0 },
{ "investor": "Rob", "stocks": 0, "options": 0, "savings": 0 },
{ "investor": "Liz", "stocks": 0, "options": 0, "savings": 0 },
];
for (let {investor, value, investment} of originalData) {
newData.find(x => x.investor === investor)[investment] += value;
}
console.log(newData);
.as-console-wrapper.as-console-wrapper { max-height: 100vh }
I would use some derivative of this:
var arrayFindObjectByProp = (arr, prop, val) => {
return arr.find( obj => obj[prop] == val );
};