Object destructuring in a loop - javascript

How can I achieve this without hardcoding the index?
const { TargetQuantity: targetQuantity1 } = res.data.d.results[0]
const { TargetQuantity: targetQuantity2 } = res.data.d.results[1]
const { TargetQuantity: targetQuantity3 } = res.data.d.results[2]
const { TargetQuantity: targetQuantity4 } = res.data.d.results[3]

try this:
const results = [
{ TargetQuantity: 1 },
{ TargetQuantity: 2 },
{ TargetQuantity: 3 },
{ TargetQuantity: 4 }
];
results.map((item, i) => {
let str ="TargetQuantity"+ (i+1) +" = item.TargetQuantity";
eval(str)
});
This will create global variables TargetQuantity1,TargetQuantity2, TargetQuantity3 ... and so on

const results = [
{TargetQuantity: 1},
{TargetQuantity: 2},
{TargetQuantity: 3},
{TargetQuantity: 4}
];
(function (context){
for(let i = 0; i < results.length; i++){
context[`targetQuantity${i+1}`] = results[i].TargetQuantity;
}
})(this);
console.log(targetQuantity3);
But why would you wanna do that?

Related

Issue arranging values in ascending order [duplicate]

This question already has answers here:
Sort Array Elements (string with numbers), natural sort
(8 answers)
Closed 11 months ago.
I am trying to arrange given values in ascending orders
const value = [
{ val: "11-1" },
{ val: "12-1b" },
{ val: "12-1a" },
{ val: "12-700" },
{ val: "12-7" },
{ val: "12-8" },
];
I am using code below to sort this in ascending order:
value.sort((a,b)=>(a.val >b.val)? 1:((b.val>a.val)?-1:0));
The result of this sort is in the order 11-1,12-1a, 12-1b, 12-7, 12-700, 12-8. However, I want the order to be 11-1,12-1a, 12-1b, 12-7, 12-8, 12-700.
How can I achieve that?
If you're only interested of sorting by the value after the hyphen you can achieve it with this code:
const value = [
{val:'12-1'},
{val:'12-700'},
{val:'12-7'},
{val:'12-8'},
];
const sorted = value.sort((a,b) => {
const anum = parseInt(a.val.split('-')[1]);
const bnum = parseInt(b.val.split('-')[1]);
return anum - bnum;
});
console.log(sorted);
updated the answer as your question update here's the solution for this:
const value = [{ val: '11-1' }, { val: '12-1b' }, { val: '12-1a' }, { val: '12-700' }, { val: '12-7' }, { val: '12-8' }];
const sortAlphaNum = (a, b) => a.val.localeCompare(b.val, 'en', { numeric: true });
console.log(value.sort(sortAlphaNum));
You can check the length first and then do the sorting as follow:
const value = [
{ val: "12-1" },
{ val: "12-700" },
{ val: "12-7" },
{ val: "12-8" },
];
const result = value.sort(
(a, b)=> {
if (a.val.length > b.val.length) {
return 1;
}
if (a.val.length < b.val.length) {
return -1;
}
return (a.val >b.val) ? 1 : ((b.val > a.val) ? -1 : 0)
}
);
console.log(result);
little change's to #Christian answer it will sort before and after - value
const value = [{ val: '12-1' }, { val: '12-700' }, { val: '11-7' }, { val: '12-8' }];
const sorted = value.sort((a, b) => {
const anum = parseInt(a.val.replace('-', '.'));
const bnum = parseInt(b.val.replace('-', '.'));
return anum - bnum;
});
console.log(sorted);
If you want to check for different values both before and after the hyphen and include checking for letters, the solution at the end will solve this.
Here's what I did:
Created a regex to split the characters by type:
var regexValueSplit = /(\d+)([a-z]+)?-(\d+)([a-z]+)?/gi;
Created a comparison function to take numbers and letters into account:
function compareTypes(alpha, bravo) {
if (!isNaN(alpha) && !isNaN(bravo)) {
return parseInt(alpha) - parseInt(bravo);
}
return alpha > bravo;
}
Split the values based on regexValueSplit:
value.sort((a, b) => {
let valuesA = a.val.split(regexValueSplit);
let valuesB = b.val.split(regexValueSplit);
This produces results as follows (example string "12-1a"):
[
"",
"12",
null,
"1",
"a",
""
]
Then, since all the split arrays should have the same length, compare each value in a for loop:
for (let i = 0; i < valuesA.length; i++) {
if (valuesA[i] !== valuesB[i]) {
return compareTypes(valuesA[i], valuesB[i]);
}
}
// Return 0 if all values are equal
return 0;
const value = [{
val: "11-1"
},
{
val: "12-1b"
},
{
val: "12-1a"
},
{
val: "12-700"
},
{
val: "12-7"
},
{
val: "12-8"
},
];
var regexValueSplit = /(\d+)([a-z]+)?-(\d+)([a-z]+)?/gi;
function compareTypes(alpha, bravo) {
if (!isNaN(alpha) && !isNaN(bravo)) {
return parseInt(alpha) - parseInt(bravo);
}
return alpha > bravo;
}
value.sort((a, b) => {
let valuesA = a.val.split(regexValueSplit);
let valuesB = b.val.split(regexValueSplit);
for (let i = 0; i < valuesA.length; i++) {
if (valuesA[i] !== valuesB[i]) {
return compareTypes(valuesA[i], valuesB[i]);
}
}
return 0;
});
console.log(JSON.stringify(value, null, 2));
Since you are sorting on string values, try using String.localeCompare for the sorting.
Try sorting on both numeric components of the string.
const arr = [
{val:'12-1'},
{val:'11-900'},
{val:'12-700'},
{val:'12-7'},
{val:'11-1'},
{val:'12-8'},
{val:'11-90'},
];
const sorter = (a, b) => {
const [a1, a2, b1, b2] = (a.val.split(`-`)
.concat(b.val.split(`-`))).map(Number);
return a1 - b1 || a2 - b2; };
console.log(`Unsorted values:\n${
JSON.stringify(arr.map(v => v.val))}`);
console.log(`Sorted values:\n${
JSON.stringify(arr.sort(sorter).map(v => v.val))}`);

Array of objects how do i check for deeply nested text string duplicates & remove from array?

I have an array of objects
Deep inside those objects is a text string
I want to check if other objects in the same array have the same text string / are duplicates.
Then i need a new array with those duplicates removed.
I thought this would be quite simple but it's been testing my intellect for two days now.
const arr = [
{..obj 1}
{..obj 2}
{..obj 3}
{
id: 4,
uid: 24872-2847-249249892842,
tags: ['some', 'stuff'],
type: "blogpage",
href: "https://link-to-stuff",
first_publication_date: "2020-02-12T16:05:04+0000",
last_publication_date: "2020-02-18T21:52:06+0000",
data: {
...some stuff
heading: [
{ type: "heading1", text: "Here Is My Text I Need To Check Duplicates
Of"}
]
}
}
{..obj 5}
{..obj 6}
{..obj 7}
{..obj 8}
{..obj 9}
{..obj 10}
]
I figured something like:
filterOutDuplicates = (blogIndexContent) => {
let arr = blogIndexContent.pages;
let results = [];
arr.map(each => {
if (!results || !results.length) {
results.push(each);
} else {
for (let i = 0; i < results.length; i++) {
const headline = results[i].data.heading[0].text;
if (headline === each.data.heading[0].text) {
return;
} else {
return results.push(each);
}
}
}
})
console.log('Results :', results); // <-- this just gives me the same 9 blog stories again, no duplicates removed.
}
What am i doing wrong guys?
If you dont mind using lodash, it could be easily solved using _.uniqBy
const withoutDups = _.uniqBy(arr, 'data.heading[0].text')
Try this
const arr = [
{
id: 4,
data: {
heading: [
{
type: "heading1",
text: "Here Is My Text I Need To Check Duplicates Of"
}
]
}
},
{
id: 5,
data: {
heading: [
{
type: "heading1",
text: "Here Is My Text I Need To Check Duplicates Of"
}
]
}
},
{
id: 6,
data: {
heading: [
{
type: "heading1",
text: "Not Duplicates"
}
]
}
}
];
const withoutDuplicates = arr.reduce(
(prev, curr) =>
prev
.map(d => d["data"]["heading"][0]["text"])
.includes(curr["data"]["heading"][0]["text"])
? [curr]
: [...prev, curr],
[]
);
console.log(withoutDuplicates);
Slight changes to your code
1) remove using map, have loop over array.
2) Build the uniq object with keys. (Here headline is what we want)
3) Add to results array only when key is not in uniq
let arr = blogIndexContent.pages;
let results = [];
const uniq = {};
for (let i = 0; i < arr.length; i++) {
const headline = arr[i].data.heading[0].text;
if (!(headline in uniq)) {
results.push(each);
uniq[each] = 1;
}
}
console.log("Results :", results);
This should work for you:
filterOutDuplicates = blogIndexContent => {
let arr = blogIndexContent.pages
const result = []
arr.forEach(each => {
if (result.length === 0) {
result.push(each)
}
else {
const headline = each.data.heading[0].text
let found = false
for (let i = 0; i < result.length; i++) {
if (result[i].data.heading[0].text === headline) {
found = true
break
}
}
if (!found) {
result.push(each)
}
}
})
console.log('Results :', results)
}

How to create a nested object from data using JavaScript?

Before
This is an object with multiple rows:
{
"functions": [
{
"package_id": "2",
"module_id": "2",
"data_id": "2"
},
{
"package_id": "1",
"module_id": "1",
"data_id": "2"
},
{
"package_id": "2",
"module_id": "3",
"data_id": "3"
}
]
}
Desired result
I want this to return into a "nested" Object like below, without duplicates:
{
"packages": [
{
"package_id": "2",
"modules": [
{
"module_id": "2",
"data": [
{
"data_id": "2"
}
]
},
{
"module_id": "3",
"data": [
{
"data_id": "3"
}
]
}
]
},{
"package_id": "1",
"modules": [
{
"module_id": "1",
"data": [
{
"data_id": "2"
}
]
}
]
}
]
}
I've already tried loops inside loops, with constructing multiple arrays and objects. Which causes duplicates or overriding objects into single ones. Is there a more generic way to generate this with JavaScript? (It's for an Angular (6) project.
Example 1
getFunctionPackage() {
var fList = this.functionList;
var dArr = [];
var dObj = {};
var pArr = [];
var pObj = {};
var mArr = [];
var mObj = {};
for (var key in fList) {
pObj['package_id'] = fList[key]['package_id'];
mObj['module_id'] = fList[key]['module_id'];
dObj['data_id'] = fList[key]['data_id'];
for (var i = 0; i < pArr.length; i++) {
if (pArr[i].package_id != pObj['package_id']) {
pArr.push(pObj);
}
for (var x = 0; x < mArr.length; x++) {
if (pArr[i]['modules'][x].module_id != mObj['module_id']) {
mArr.push(mObj);
}
for (var y = 0; y < dArr.length; y++) {
if (pArr[i]['modules'][x]['datas'][y].data_id != dObj['data_id']) {
dArr.push(dObj);
}
}
}
}
if (dArr.length == 0) {
dArr.push(dObj);
}
mObj['datas'] = dArr;
if (mArr.length == 0) {
mArr.push(mObj);
}
pObj['modules'] = mArr;
if (pArr.length == 0) {
pArr.push(pObj);
}
dObj = {};
mObj = {};
pObj = {};
}
}
Example 2:
Results in skipping cause of the booleans
var fList = this.functionList;
var dArr = [];
var dObj = {};
var pArr = [];
var pObj = {};
var mArr = [];
var mObj = {};
var rObj = {};
for (var key in fList) {
pObj['package_id'] = fList[key]['package_id'];
mObj['module_id'] = fList[key]['module_id'];
dObj['data_id'] = fList[key]['data_id'];
var pfound = false;
var mfound = false;
var dfound = false;
for (var i = 0; i < pArr.length; i++) {
if (pArr[i].package_id == pObj['package_id']) {
for (var x = 0; x < mArr.length; x++) {
if (pArr[i]['modules'][x].module_id == mObj['module_id']) {
for (var y = 0; y < dArr.length; y++) {
if (pArr[i]['modules'][x]['datas'][y].data_id == dObj['data_id']) {
dfound = true;
break;
}
}
mfound = true;
break;
}
}
pfound = true;
break;
}
}
if (!dfound) {
dArr.push(dObj);
mObj['datas'] = dArr;
dObj = {};
}
if (!mfound) {
mArr.push(mObj);
pObj['modules'] = mArr;
mObj = {};
}
if (!pfound) {
pArr.push(pObj);
pObj = {};
}
dArr = [];
mArr = [];
}
rObj['packages'] = pArr;
console.log(rObj);
Here's a more generic approach using Array#reduce() to create a grouped object based on the package id as keys. You can use any loop to build this same object ...for() or forEach() for example.
Then use Object.values() to get the final array from that grouped object
Using methods like Array#find() simplifies traversing to see if a module exists already or not within each package
const grouped = data.functions.reduce((a, c )=>{
// if group object doesn't exist - create it or use existing one
a[c.package_id] = a[c.package_id] || {package_id : c.package_id, modules: [] }
// store reference to the group modules array
const mods = a[c.package_id].modules
// look within that group modules array to see if module object exists
let module = mods.find(mod => mod.module_id === c.module_id)
if(!module){
// or create new module object
module = {module_id: c.module_id, data:[]}
// and push it into modules array
mods.push(module);
}
// push new data object to module data array
module.data.push({data_id: c.data_id})
return a
}, {})
// create final results object
const res = { packages : Object.values(grouped) }
console.log(res)
.as-console-wrapper {max-height: 100%!important;}
<script>
const data = {
"functions": [{
"package_id": "2",
"module_id": "2",
"data_id": "2"
},
{
"package_id": "1",
"module_id": "1",
"data_id": "2"
},
{
"package_id": "2",
"module_id": "3",
"data_id": "3"
}
]
}
</script>

How to insert objects through javascript?

I have stored group of objects into one array called 'resData' and i'm having one more array of data called 'approvedIds', there have included all approved id's. Here i want to match these two arrays and add one new key into 'resData' array like 'approveStatus:"approve"'. How to do this one in javascript?
All data's,
var resData = [
{
firstName:"Jhon",
lastName:"adam",
emailId:"jhn12#gmail.com",
id:"01"
},
{
firstName:"Kyle",
lastName:"Miller",
emailId:"kl12#gmail.com",
id:"02"
},
{
firstName:"Jhonathan",
lastName:"adam",
emailId:"jadm12#gmail.com",
id:"03"
},
{
firstName:"Lewis",
lastName:"harber",
emailId:"lewh12#gmail.com",
id:"04"
}
];
Approved id's array,
var approvedIds = ['01', '03'];
My output will be like this,
var resData = [
{
firstName:"Jhon",
lastName:"adam",
emailId:"jhn12#gmail.com",
id:"01",
approveStatus:'approved'
},
{
firstName:"Kyle",
lastName:"Miller",
emailId:"kl12#gmail.com",
id:"02"
},
{
firstName:"Jhonathan",
lastName:"adam",
emailId:"jadm12#gmail.com",
id:"03",
approveStatus:'approved'
},
{
firstName:"Lewis",
lastName:"harber",
emailId:"lewh12#gmail.com",
id:"04"
}
];
You can try this. Use forEach and indexOf functions
var resData = [
{
firstName:"Jhon",
lastName:"adam",
emailId:"jhn12#gmail.com",
id:"01"
},
{
firstName:"Kyle",
lastName:"Miller",
emailId:"kl12#gmail.com",
id:"02"
},
{
firstName:"Jhonathan",
lastName:"adam",
emailId:"jadm12#gmail.com",
id:"03"
},
{
firstName:"Lewis",
lastName:"harber",
emailId:"lewh12#gmail.com",
id:"04"
}
];
var approvedIds = ['01', '03'];
resData.forEach(item => {
if(approvedIds.indexOf(item.id) !== -1){
item.approvedStatus = 'approved';
}
} );
console.log(resData);
Using ES6 array functions, which is more functional and doesn't alter the original objects:
var resData = [
{
firstName:"Jhon",
lastName:"adam",
emailId:"jhn12#gmail.com",
id:"01"
},
{
firstName:"Kyle",
lastName:"Miller",
emailId:"kl12#gmail.com",
id:"02"
},
{
firstName:"Jhonathan",
lastName:"adam",
emailId:"jadm12#gmail.com",
id:"03"
},
{
firstName:"Lewis",
lastName:"harber",
emailId:"lewh12#gmail.com",
id:"04"
}
];
var approvedIds = ['01', '03'];
//Solution:
var newData = resData
.filter(rd => approvedIds.indexOf(rd.id) >= 0)
.map(rd => Object.assign({}, rd, {approvedStatus: "approved"}));
console.log(newData, resData);

Write a function to iterate and pluck an inner array's objects

How could I use vanilla js or lodash to return Scene.data[i].trends into a one newArr
Output should look like this:
var newArr = superFunction();
console.log(newArr);
=> [{id:100},{id:101},{id:200},{id:201}]
Dataset:
Scenes.data = [
{
id: 0,
trends: [
{
id: 100,
},
{
id: 101,
}]
},
{
id: 2,
trends: [
{
id: 200,
},
{
id: 201,
}]
}]
With lodash you can use pluck and flattern:
var result = _(scenes).pluck('trends').flattern().value();
Or maybe reduce (plain js):
var result = scenes.reduce(function(prev, curr) {
return prev.concat(curr.trends);
}, []);
You can do this :
var newArr = [].concat.apply([], Scenes.data.map(function(v){ return v.trends }));
Demonstration
You can do it like this:
var newArr = [];
Scenes.data.forEach(function(x) {
x.trends.forEach(function(trend) {
var obj = {};
for(var key in trend) {
if (trend.hasOwnProperty(key)) {
obj["" + key + ""] = trend[key];
}
}
newArr.push(obj);
});
});
Fiddle

Categories