I have 2 arrays
I want this:
[{name: 'Sweater', qty: 1}, {name: 'Skirt', qty: 3}, {name: 'Socks', qty: 2}]
but I get
qtyList = [1, 3, 2]
data = [{name: 'Sweater', qty: 1}, {name: 'Skirt', qty: 1}, {name: 'Socks', qty: 1}]
let assignQty = data.map((x, id) => {
qtyList.map((y, idx) => {
if (idx == id) return x.qty = y
})
})
console.log('assignQty', assignQty)
You're essentially zipping the 2 lists together - typically done as follows:
const qtyList = [1, 3, 2]
const data = [{name: 'Sweater', qty: 1}, {name: 'Skirt', qty: 1}, {name: 'Socks', qty: 1}]
const result = data.map((item,idx) => ({...item, qty: qtyList[idx]}))
console.log(result);
const qtyList = [1, 3, 2];
data = [{name: 'Sweater', qty: 1}, {name: 'Skirt', qty: 1}, {name: 'Socks', qty: 1}]
const updateQuantity = (list, data) => {
if (data.length !== list.length) {
return
}
for (let index = 0; index < list.length; index++) {
const element = list[index];
// udpate data
data[index] = {
name: data[index].name,
qty: element
}
}
return data;
}
console.log(updateQuantity(qtyList, data));
Use Spread syntax on item than change qty with array values
qtyList = [1, 3, 2]
data = [{name: 'Sweater', qty: 1}, {name: 'Skirt', qty: 1}, {name: 'Socks', qty: 1}]
let assignQty = data.map((item, index) => (
{
...item,
qty: qtyList[index]}
));
console.log("assignQty", assignQty );
Without using the spread operator, update the required field and then return x.
qtyList = [1, 3, 2]
data = [{name: 'Sweater', qty: 1}, {name: 'Skirt', qty: 1}, {name: 'Socks', qty: 1}]
var assignQty = data.map((x, id) => {x.qty=qtyList[id];return x;})
console.log('assignQty', assignQty)
This is my approach to your question. In your example, you were trying to map two arrays into one. This approach "loops" the data array containing the objects you want to change.
Using the index of each object it sets the item.qty to the value in qtyList[index].
qtyList = [1, 3, 2];
data = [{
name: 'Sweater',
qty: 1
}, {
name: 'Skirt',
qty: 1
}, {
name: 'Socks',
qty: 1
}];
let assignQty = data.map((item, index) => {
item.qty = qtyList[index];
return item;
});
console.log(assignQty)
Related
I just started learning JavaScript, I have this type of array, how I can turn this array of objects into key-value pairs like below, Any source and reference is acceptable.
Sample Array:
[
{Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1},
{Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1}
]
Expected Result:
{
"6d7e75e6-c58b-11e7-95-ac162d77eceb":1,
"6d2e75e6-c58b-11e7-95-ac162d77eceb":1
}
Using Array.prototype.Reduce:
const arr = [{Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1},{Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1}];
const result = arr.reduce((acc, { Id, qty }) => ({ ...acc, [Id]: qty }), {});
console.log(result);
Another approach, a little more beginner friendly.
const arr = [
{Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1},
{Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1}
];
const newObject = {}; // empty object
// loop over each element of the array
arr.forEach(element => {
// the key is the element identifier (Id) and the value is the element quantity (qty)
newObject[element.Id] = element.qty;
});
You can use a loop and add the item.Id as the key and the item.qty as the value in an empty object.
let arr = [{Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1},{Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1}]
let obj = {}
arr.forEach(item => {
obj[item.Id] = item.qty
})
console.log(obj)
You can easily achieve this result using forEach in a single line of code.
const arr = [
{ Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1 },
{ Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1 },
];
const result = {};
arr.forEach(({ Id, qty }) => (result[Id] = qty));
console.log(result);
You can achieve the desired result with below code
//input array
const arrList = [
{Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1},
{Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1}
]
function findArray(arr) {
//define a new array to store Id's
let newArray = [];
//iterate through array items
arr.forEach(item => {
newArray.push(item.Id);
});
return newArray;
}
//call findArray function to get desired output
console.log(findArray(arrList));
Using Object.fromEntries()
const
array = [{ Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1 }, { Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1 }],
object = Object.fromEntries(array.map(({ Id, qty }) => [Id, qty]));
console.log(object);
or, for some fragile novelty...
const
array = [{ Id: "6d7e75e6-c58b-11e7-95-ac162d77eceb", qty: 1 }, { Id: "6d2e75e6-c58b-11e7-95-ac162d77eceb", qty: 1 }],
object = Object.fromEntries(array.map(Object.values));
console.log(object);
I have a object obj, in which how to remove duplicate in info and apply the sum of quantity qty to key total in javascript.
How to remove duplicates in array object and apply sum to particular key in javascript.
function newList (obj){
return obj.map(i=>({
...i,
total: i.info.map(e => e.qty).reduce((prev, curr) => prev + curr, 0)
}));
}
var obj =[
{id:1, info:[{idx:1, qty: 1}, {idx:2, qty: 2},{idx:2, qty: 2}], code: "sample1", total: 1},
{id:2, info:[{idx:3, qty: 2}, {idx:4, qty: 2}], code: "sample2", total: 2}
]
Expected Output:
[
{id:1, info:[{idx:1, qty: 1}, {idx:2, qty: 2}], code: "sample1", total: 3},
{id:2, info:[{idx:3, qty: 2}, {idx:4, qty: 2}], code: "sample2", total: 4}
]
You can make use of reduce and Map(to unique the rows):
var obj =[
{id:1, info:[{idx:1, qty: 1}, {idx:2, qty: 2},{idx:2, qty: 2}], code: "sample1", total: 1},
{id:2, info:[{idx:3, qty: 2}, {idx:4, qty: 2}], code: "sample2", total: 2}
];
var result = obj.reduce((acc, elem)=>{
elem.info = [...new Map(elem.info.map(i=>[i.idx, i])).values()];
elem.total = elem.info.reduce((sum, {qty})=>sum+qty,0);
acc = [...acc, elem];
return acc;
},[]);
console.log(result);
Please try the following example, although my result differs from the totals that show as the expected result. Try it please
const obj = [
{
id: 1,
info: [
{ idx: 1, qty: 1 },
{ idx: 2, qty: 2 },
{ idx: 2, qty: 2 },
],
code: "sample1",
total: 1,
},
{
id: 2,
info: [
{ idx: 3, qty: 2 },
{ idx: 4, qty: 2 },
],
code: "sample2",
total: 2,
},
];
let output = obj.map((entry) => {
return {
...entry,
info: entry.info.reduce((prev, curr) => {
const item = prev.find(
(element) => element.idx === curr.idx && element.qty == curr.qty
);
if (!item) {
prev = [...prev, curr];
}
return prev;
}, []),
};
});
output = output.map((entry) => {
return {
...entry,
total: entry.total + entry.info.reduce((prev, curr) => prev + curr.qty, 0),
};
});
console.dir(output, { depth: null, color: true });
See
Array.prototype.find()
Array.prototype.reduce()
function newList(obj) {
return obj.map(i => ({
...i,
...reduceInfo(i.info)
}));
}
function reduceInfo(array) {
return array.reduce((a, c) => {
a.info = a.info || [];
a.total = a.total || 0;
if (!a.info.some(element => c.idx === element.idx && c.qty === element.qty)) {
a.info.push(c);
a.total = a.total + c.qty;
}
return a;
}, {});
}
var obj = [
{ id: 1, info: [{ idx: 1, qty: 1 }, { idx: 2, qty: 2 }, { idx: 2, qty: 2 }], code: "sample1", total: 1 },
{ id: 2, info: [{ idx: 3, qty: 2 }, { idx: 4, qty: 2 }], code: "sample2", total: 2 }
]
console.log(JSON.stringify(newList(obj)));
I have 2 arrays of objects
var array1 = [
{id: 1, name:'fruit', rating:5},
{id: 4, name:'vegetable', rating: 3},
{id: 8, name:'meat', rating:1}
];
var array2 = [
{alimentId: 1, quantity: 2},
{alimentId: 4, quantity: 2},
{alimentId: 8, quantity: 4}
]
and I want to get a new the array1 such that
var array = [
{id: 1, name:'fruit'},
{id: 4, name:'vegetable'},
]
which has only the elements with quantity 2 matching the alimentId with the id.
I'm always getting confused with arrays and objects manipulations.. Please help
I believe the following code will solve your problem:
const func = (arr1, arr2) => {
return arr1.filter(obj => {
const objToCheck = arr2.filter(element => element.alimentId === obj.id);
return objToCheck[0].quantity === 2;
});
};
You also can send the wanted value(2) and the key name(quantity) as params.
var array1 = [
{id: 1, name:'fruit', rating:5},
{id: 4, name:'vegetable', rating: 3},
{id: 8, name:'meat', rating:1}
];
var array2 = [
{alimentId: 1, quantity: 2},
{alimentId: 4, quantity: 2},
{alimentId: 8, quantity: 4}
]
function filter(array1, array2) {
return array1
.filter(it => array2 // filter array1 by array2
.filter(it => it.quantity === 2) // filter your array2 by field quantity = 2
.map(it => it.alimentId) // pull out array of alimentId
.includes(it.id) // check array2.alimentId includes array1.id
)
}
console.log(filter(array1, array2))
use this function
const common_elements = (arr1, arr2, quantity) => {
let res = []
arr1.forEach(el1 => {
arr2.forEach(el2 => {
if(el1.id === el2.alimentId && el2.quantity === quantity) {
res.push(el1)
}
});
});
return res
}
You can do a reduce:
var array3 = array1.reduce((acc ,val ,index) => {
if (val.id=array2[index].alimentId) {
acc =[...acc, {id: val.id, name: val.name}]
}
return acc;
},[]);
var array1 = [
{id: 1, name:'fruit', rating:5},
{id: 4, name:'vegetable', rating: 3},
{id: 8, name:'meat', rating:1}
];
var array2 = [
{alimentId: 1, quantity: 2},
{alimentId: 4, quantity: 2},
{alimentId: 8, quantity: 4}
]
const commonArray = array2.filter(item => item.quantity === 2 && array1.find(el => el.id===item.alimentId));
console.log(commonArray)
So I have the next information, what I want to achieve is filter the array of objects and sum the qty of the objects repeated
//Original Data
var data = {
sublists = [
{ item: 1, qty: 2},
{ item: 2, qty: 2},
{ item: 3, qty: 2},
{ item: 1, qty: 5}
{ item: 3, qty: 3}
],
...
};
//This is what I want to achieve
var result = {
sublists = [
{ item: 1, qty: 7},
{ item: 2, qty: 2},
{ item: 3, qty: 5}
],
...
};
So far what I got is the items name that repeat and an object that has the data of this variables
var repeatedObjects = {
1: [{ item: 1, qty: 2}, { item: 1, qty: 5}],
3: [{ item: 3, qty: 2}, { item: 3, qty: 3}]
}
var repeatedItems = [1, 3];
But Im stuck at reducing the object so I can get the original data, with just one of the repeated objects and the sum of all of them. Any ideas?
Create an itemByFreq json object like below
var data = {
sublists : [
{ item: 1, qty: 2},
{ item: 2, qty: 2},
{ item: 3, qty: 2},
{ item: 1, qty: 5},
{ item: 3, qty: 3}
]
};
var itemByFreq = {};
for(var i=0;i<data.sublists.length;i++){
var ji = data.sublists[i];
itemByFreq[ji.item] = (itemByFreq[ji.item] || 0) + ji.qty;
}
console.log(itemByFreq);
var duplicateItems = [];
for(var key in itemByFreq)
duplicateItems.push({item: key,qty: itemByFreq[key]});
console.log(duplicateItems);
It could be done using Map & reduce :)
const dataSample = {
sublists: [
{ item: 1, qty: 2},
{ item: 2, qty: 2},
{ item: 3, qty: 2},
{ item: 1, qty: 5},
{ item: 3, qty: 3}
],
};
const mergeItems = list => {
return [...list.reduce((acc, val) => {
const oldVal = acc.get(val.item) || { qty: 0 }
const newVal = {
...val,
qty: oldVal.qty + val.qty
}
acc.set(val.item, newVal)
return acc
}, new Map()).values()]
}
console.log(mergeItems(dataSample.sublists))
If you fancy using lodash to do this in one line, you could also use this
const _ = require("lodash");
const data = [
{"item": 1, "qty": 2},
{"item": 2, "qty": 2},
{"item": 3, "qty": 2},
{"item": 1, "qty": 5},
{"item": 3, "qty": 3}
];
const result = _.map(_.groupBy(data, i => i.item), (o, idx) => {
return {"item": idx, "qty": _.sumBy(o, i => i.qty)};
});
console.log(result);
Using reduce will simplify
const update = data =>
Object.values(
data.sublists.reduce((acc, curr) => {
acc[curr.item] =
curr.item in acc
? { ...acc[curr.item], qty: acc[curr.item].qty + curr.qty }
: { ...curr };
return acc;
}, {})
);
var data = {
sublists: [
{ item: 1, qty: 2 },
{ item: 2, qty: 2 },
{ item: 3, qty: 2 },
{ item: 1, qty: 5 },
{ item: 3, qty: 3 }
]
};
const res = { sublists: update(data) };
console.log(res);
I have two arrays like this:
let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];
Now I want a result like this:
result = [ {name: "apple", prices: [{id: 1, price: 50}, {id: 1, price: 40}]}, {name: "orange", prices: [{id: 2, price: 30}]}, {name: "others", prices: [{id: null, price: 80}]}]
I want to map the elements of the array a to the name of the second array b on the basis of their ids.
Here's an approach that using reduce to build a lookup set and avoid repeated searches in b. Another reduction pass builds the result arrays by name using the lookup table. Lastly, map is used to format the result.
Time complexity is linear (three passes with a lot of constant time object lookups).
let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];
const lookup = b.reduce((a, e) => {
a[e.id] = e.name;
return a;
}, {});
const result = Object.entries(
a.reduce((a, e) => {
const key = lookup[e.id] || "others";
if (!(key in a)) {
a[key] = [];
}
a[key].push(e);
return a;
}, {})
).map(e => ({name: e[0], prices: e[1]}));
console.log(result);
It would be more logical to not repeat the id in the prices part of the result, since the id belongs with the name.
I would suggest using a temporary map (for efficiency):
let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];
const map = new Map(b.map(o => [o.id, Object.assign(o, { prices: [] })]))
.set(null, {id: null, name: "others", prices: []});
a.forEach(o => map.get(o.id).prices.push(o.price));
const result = [...map.values()];
console.log(result);
Yes, you can do it simply with a map and a filter
let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];
b.map(({ name, id }) => ({
name,
id,
prices: a.filter(item => item.id === id).map(({ price }) => price)
}));
You can do this with a single Array.reduce and Object.values if you start by combining the 2 arrays together:
let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];
const result = Object.values([...b, ...a].reduce((r, c) => {
if ('name' in c || c.id == null)
r[c.id || 'others'] = ({name: c.name || 'others', prices: []})
if ('name' in c)
return r
else if (c.id != null)
r[c.id].prices.push(c)
else
r['others'].prices.push(c)
return r
}, {}))
console.log(result)
The idea is to start with the one containing the names so the grouping creates first the object groupings and then just fill the group arrays.