Organizing key value pairs value in comma separated fashion - javascript

I have two array like this:
var actval = [
0: "3"
1: "22-Nov-2018 15:32:36 IST"
2: "22-Nov-2018 15:32:40 IST"
3: "3"
4: "22-Nov-2018 15:32:36 IST"
5: "22-Nov-2018 15:32:40 IST"
6: "3"
7: "22-Nov-2018 15:32:36 IST"
8: "22-Nov-2018 15:32:40 IST"
]
var id = [
0: "STATUS"
1: "STARTTIME"
2: "ENDTIME"
3: "STATUS"
4: "STARTTIME"
5: "ENDTIME"
6: "STATUS"
7: "STARTTIME"
8: "ENDTIME"
]
What I want to do is make a final array which would have keys as STATUS, STARTTIME, ENDTIME and each of the keys can have multiple values like this:
finalarray = [
STATUS: ["3", "3", "3"]
STARTTIME: ["22-Nov-2018 15:32:36 IST", "22-Nov-2018 15:32:36 IST", "22-Nov-2018 15:32:36 IST"]
ENDTIME: ["22-Nov-2018 15:32:40 IST", "22-Nov-2018 15:32:40 IST", "22-Nov-2018 15:32:40 IST"]
]
For this I have tried this approach :
for (i = 0; i < id.length; i++) {
currentKey = id[i];
currentVal = actval[i];
result[currentKey] = currentVal;
}
but it only gives me one value for each key not every value:
How can i get the each value in that array linked to that key?

Solved Just adding one check in your code
try this:
var result = [];
for (i = 0; i < id.length; i++) {
let currentKey = id[i];
let currentVal = actval[i];
if(result[currentKey])
result[currentKey] = [...result[currentKey],currentVal];
else
result[currentKey] = [currentVal];
}

If actval always look like that and you want to extract the top 3 values you could just do a shift() something like this.
var final = {STATUS: [], STARTTIME:[], ENDTIME:[]};
for (let i=0; actval.length > i; i++) {
final.STATUS.push( actval.shift() );
final.STARTTIME.push( actval.shift() );
final.ENDTIME.push( actval.shift() );
}
What you are doing is just writing over the same array value with =.
You are always doing result['key'] = 'value';

Try this assuming actval is array not object:
finalobject = {
STATUS: actval.filter(e=>e.length===1),
STARTTIME: actval.filter((e, i)=>i%3).filter((e, i)=>i%2===0),
ENDTIME: actval.filter((e, i)=>i%3).filter((e, i)=>i%2!==0),
};
I will update question, when you will clarify some things and change this "arrays" to objects.

Related

How to find index of 'items_tolookfor' array of items in another nested Array List 'nested_data' in javascript

How to find index of 'items_tolookfor' array of items in another nested Array List 'nested_data' in javascript
const items_tolookfor = []
console.log(items_tolookfor) is as below
0: "urn:adsk.wipprod:fs.folder:co.uqbu12FFQZO6y7GxUs7cKA"
1: "urn:adsk.wipprod:fs.folder:co.uqbu12FFQZO6y7GxUs7cKA"
2: "urn:adsk.wipprod:fs.folder:co.uqbu12FFQZO6y7GxUs7cKA"
3: "urn:adsk.wipprod:fs.folder:co.uqbu12FFQZO6y7GxUs7cKA"
4: "urn:adsk.wipprod:fs.folder:co.uqbu12FFQZO6y7GxUs7cKA"
5: "urn:adsk.wipprod:fs.folder:co._rdgx-sJT36zVaGNILbvvQ"
length: 6
lastIndex: (...)
lastItem: (...)
[[Prototype]]
//////////////////////////////////////////////////////////
const nested_data = []
console.log(nested_data) is as follows:
0: Array(0)
length: 0
lastIndex: (...)
lastItem: (...)
[[Prototype]]: Array(0)
1: Array(0)
length: 0
lastIndex: (...)
lastItem: (...)
[[Prototype]]: Array(0)
2: Array(5)
0: "urn:adsk.wipprod:fs.folder:co.yoqKNIJMTmWvdxFIYGk8sg"
1: "urn:adsk.wipprod:fs.folder:co.eGqoz0IlTriGsYLTKbIrIA"
2: "urn:adsk.wipprod:fs.folder:co.O4tlfhMhSACS81dsygYJSw"
3: "urn:adsk.wipprod:fs.folder:co.FBQOhzXkSa6upov-iay5EQ"
4: "urn:adsk.wipprod:fs.folder:co.nXNGKsqTQUGr_hcTXy6U5g"
5: "urn:adsk.wipprod:fs.folder:co.uqbu12FFQZO6y7GxUs7cKA"
length: 5
lastIndex: (...)
lastItem: (...)
[[Prototype]]: Array(0)
///////////////////////////////////////////
How would I find indices for 'items_tolookfor' in the nested array list 'nested_data'
Also, the corresponding data lies in the nested list 'nested_data' index[2][5]
I was trying this code:
console.log(items_tolookfor);
console.log(nested_data);
const found_indices = [];
for (const assdata in nested_data) {
const temp = [];
for (const fldr_data in items_tolookfor) {
const temp1 = assdata.indexOf(fldr_data);
temp.push(temp1);
}
found_indices.push(temp);
}
Expected result to be a console log output array with matching data for items_to_look_for array object found in nested_data array object, which is 0: [2][5], 1:[2][5], 2:[2][5], 3: [2][5], 4: [2][5], 5:[][]
Here's how you could go about that:
const items_to_look_for = [
'urn:adsk.wipprod:fs.folder:co.uqbu12FFQZO6y7GxUs7cKA',
'urn:adsk.wipprod:fs.folder:co.uqbu12FFQZO6y7GxUs7cKA',
'urn:adsk.wipprod:fs.folder:co.uqbu12FFQZO6y7GxUs7cKA',
'urn:adsk.wipprod:fs.folder:co.uqbu12FFQZO6y7GxUs7cKA',
'urn:adsk.wipprod:fs.folder:co.uqbu12FFQZO6y7GxUs7cKA',
'urn:adsk.wipprod:fs.folder:co._rdgx-sJT36zVaGNILbvvQ'
];
const nested_data = [
[],
[],
[
'urn:adsk.wipprod:fs.folder:co.yoqKNIJMTmWvdxFIYGk8sg',
'urn:adsk.wipprod:fs.folder:co.eGqoz0IlTriGsYLTKbIrIA',
'urn:adsk.wipprod:fs.folder:co.O4tlfhMhSACS81dsygYJSw',
'urn:adsk.wipprod:fs.folder:co.FBQOhzXkSa6upov-iay5EQ',
'urn:adsk.wipprod:fs.folder:co.nXNGKsqTQUGr_hcTXy6U5g',
'urn:adsk.wipprod:fs.folder:co.uqbu12FFQZO6y7GxUs7cKA'
]
];
function findIndexRecursive(item, data) {
for (let i = 0, len = data.length; i < len; i++) {
if (data[i] === item) {
return [i];
} else if (data[i] instanceof Array) {
const nestedIndex = findIndexRecursive(item, data[i]);
if (nestedIndex) {
return [i].concat(nestedIndex);
}
}
}
return null;
}
for (const item of items_to_look_for) {
console.log(findIndexRecursive(item, nested_data));
}

Add new dimension dynamically to an array using recursive function

I have an array like this:
0: "SuSPENSE"
1: "Subcontractor Expense"
2: "Data Entry"
3: "Design"
4: "Programming"
5: "Subcontractor Expense - Other"
6: "Total Subcontractor Expense"
7: "Technology-Communication"
8: "Licenses"
9: "Domain Hosting Fee"
10: "Internet"
11: "Internet Servers"
12: "Internet - Other"
13: "Total Internet"
14: "Telephone"
15: "Call Center"
16: "Cellular Phones"
17: "Fax"
18: "Telephone - Other"
19: "Total Telephone"
20: "Hardware/Software"
21: "Computer Software"
22: "Hardware/Software - Other"
23: "Total Hardware/Software"
24: "Technology-Communication - Other"
25: "Total Technology-Communication"
This is a list of categories and subcategories. For example, "Subcontractor Expense" is a sub-category and ends with "Total Subcontractor Expense". Same for "Internet" and "Total Internet". The template is always the same, category starts with "(name)" and ends with "Total (name)". But each category can have many levels of sub-categories, like a tree. I'm trying to parse this array into a JSON-like array or a multidimensional array using recursive function, but I never know what the maximum depth is. I tried to do the following using js:
var parsedArray = [];
var items = getLineItems("Expense", "Total Expense"); //This is a function to return the mentioned array
var newArray = parseArray(items, "Expense");
function parseArray(items, category){
var lineItems = [];
for(var i = 0; i < items.length; i++){
var inArray = $.inArray("Total " + items[i], items);
if(inArray !== -1){
parseArray(getLineItems(items[i], "Total " + items[i]), items[i]);
}
else {
lineItems.push(items[i]);
}
}
parsedArray[category] = lineItems;
}
But this recursive function never goes deeper then 2 levels. Is is possible to generate something like this?
"SuSPENSE"
"Subcontractor Expense"
"Data Entry"
"Design"
"Programming"
"Subcontractor Expense - Other"
"Technology-Communication"
"Licenses"
"Domain Hosting Fee"
"Internet"
"Internet Servers"
"Internet - Other"
"Telephone"
"Call Center"
"Cellular Phones"
"Fax"
"Telephone - Other"
"Hardware/Software"
"Computer Software"
"Hardware/Software - Other"
"Technology-Communication - Other"
I'm still guessing about your output format. Here is a recursive solution that gives the format I asked about in the comments:
[
{name: "SuSPENSE"},
{name: "Subcontractor Expense", children: [
{name: "Data Entry"},
{name: "Design"},
{name: "Programming"},
{name: "Subcontractor Expense - Other"}
]},
{name: "Technology-Communication", children: [
//...
]}
]
const restructure = (
[s = undefined, ...ss],
index = s == undefined ? -1 : ss .indexOf ('Total ' + s)
) =>
s == undefined
? []
: index > -1
? [
{name: s, children: restructure (ss .slice (0, index))},
... restructure (ss .slice (index + 1))
]
: [{name: s}, ... restructure (ss)]
const data = ["SuSPENSE", "Subcontractor Expense", "Data Entry", "Design", "Programming", "Subcontractor Expense - Other", "Total Subcontractor Expense", "Technology-Communication", "Licenses", "Domain Hosting Fee", "Internet", "Internet Servers", "Internet - Other", "Total Internet", "Telephone", "Call Center", "Cellular Phones", "Fax", "Telephone - Other", "Total Telephone", "Hardware/Software", "Computer Software", "Hardware/Software - Other", "Total Hardware/Software", "Technology-Communication - Other", "Total Technology-Communication"]
console .log (
restructure (data)
)
.as-console-wrapper {min-height: 100% !important; top: 0}
Note that in one of the recursive cases, we call our main function twice. Once for the nested data and once for the remainder of the array.
Another possible structure, one which I like less, but which might meet your needs, looks like this:
[
"SuSPENSE",
{"Subcontractor Expense": [
"Data Entry", "Design", "Programming", "Subcontractor Expense - Other"
]},
{ "Technology-Communication": [
// ...
]}
]
This could be achieved with only a minor modification:
const restructure = (
[s = undefined, ...ss],
index = s == undefined ? -1 : ss .indexOf ('Total ' + s)
) =>
s == undefined
? []
: index > -1
? [
{[s]: restructure (ss .slice (0, index))},
... restructure (ss .slice (index + 1))
]
: [s, ... restructure (ss)]
Update
This variant does the same as the first, but may look more familiar to people not used to my expression-heavy style:
const restructure = ([s = undefined, ...ss]) => {
if (s == undefined) {return []}
const index = ss .indexOf ('Total ' + s)
return index < 0
? [{name: s}, ... restructure (ss)]
: [
{name: s, children: restructure (ss .slice (0, index))},
... restructure (ss .slice (index + 1))
]
}
You could do this by checking if the current element has the corresponding element that starts with the word Total and then continues with the text of the current element and if so you increment the level. When the current element starts with word total then you decrement the level.
const data = {"0":"SuSPENSE","1":"Subcontractor Expense","2":"Data Entry","3":"Design","4":"Programming","5":"Subcontractor Expense - Other","6":"Total Subcontractor Expense","7":"Technology-Communication","8":"Licenses","9":"Domain Hosting Fee","10":"Internet","11":"Internet Servers","12":"Internet - Other","13":"Total Internet","14":"Telephone","15":"Call Center","16":"Cellular Phones","17":"Fax","18":"Telephone - Other","19":"Total Telephone","20":"Hardware/Software","21":"Computer Software","22":"Hardware/Software - Other","23":"Total Hardware/Software","24":"Technology-Communication - Other","25":"Total Technology-Communication"}
function toNested(data) {
const result = [];
const levels = [result]
let level = 0;
const checkChildren = (string, data) => {
return data.some(e => e === `Total ${string}`)
}
data.forEach((e, i) => {
const object = { name: e, children: []}
levels[level + 1] = object.children;
if (e.startsWith('Total')) level--;
else levels[level].push(object);
if (checkChildren(e, data.slice(i))) level++;
})
return result;
}
const result = toNested(Object.values(data));
console.log(result)

Replace months in javascript array

in this.sources I have this kind of array data:
this.sources = [
{
cost: 50000.5,
ids: { 1: "11112", 2: "1112", 3: "121212" },
months: { 1: "54548.5000", 2: "45.0000", 3: "510.5000" },
name: "test1"
},
{
cost: 12469134.5,
ids: { 1: "19689", 2: "19690", 3: "19691" },
months: { 1: "12345678.5000", 2: "0.0000", 3: "50.5000" },
name: "test2"
}
];
What I need is to replace all data in months for all cases (just to change the 4 decimals to 2) and then return the array with the same structure as it is.
What I tried:
this.sources = this.fixDecimal(this.sources);
fixDecimal(source) {
for ( let elx in source ) {
let newsource = source[elx];
for ( let x = 0; x <= 11; x++ ) {
let result = newsource.months[x];
if (result) { if (result) { result.map(y => y.toFixed(2));}
}
}
return result;
}
However this is not working at all. Is there any simple solution just to fix the decimals in months and return the same array with changed data?
The reason your solution doesnt work is because you have your values as string and you can't use toFixed on a string. The parseFloat in the snippet below mitigates that:
for(let i=0; i<dataset.length;i++){
let months = {};
// Instead of looping through a hardcoded amount, loop though all the keys:
Object.keys(dataset[i].months).forEach(function(key) {
months[key] = parseFloat(dataset[i].months[key]).toFixed(2);
});
dataset[i].months = months;
}
This is assuming that you get your results in a variable dataset, you might want to tweak this a bit.
Since all of your values are strings, and have 4 positions after the decimal separator, you can just slice() off the last two characters:
const months = {
1: "54548.5000",
2: "45.0000",
3: "510.5000"
// ...
};
for (let m in months) {
months[m] = months[m].slice(0, -2);
}
console.log(months);
This code should do what you want, without modifying the original array. Slice will remove the last 2 characters of each month (you can even use substring here: v.substring(0, v.length - 2))
:
sources = [
{
cost: 50000.5,
ids: { 1: "11112", 2: "1112", 3: "121212" },
months: { 1: "54548.5000", 2: "45.0000", 3: "510.5000" },
name: "test1"
},
{
cost: 12469134.5,
ids: { 1: "19689", 2: "19690", 3: "19691" },
months: { 1: "12345678.5000", 2: "0.0000", 3: "50.5000" },
name: "test2"
}
];
console.log(sources.map(o => ({...o, months: Object.entries(o.months).reduce((a, [k,v]) => ({...a, [k]: v.slice(0, -2)}), {})})))
Or, you could modify the original array:
sources = [
{
cost: 50000.5,
ids: { 1: "11112", 2: "1112", 3: "121212" },
months: { 1: "54548.5000", 2: "45.0000", 3: "510.5000" },
name: "test1"
},
{
cost: 12469134.5,
ids: { 1: "19689", 2: "19690", 3: "19691" },
months: { 1: "12345678.5000", 2: "0.0000", 3: "50.5000" },
name: "test2"
}
];
sources.forEach((o, i) => sources[i].months = Object.entries(o.months).reduce((a, [k,v]) => ({...a, [k]: v.slice(0, -2)}), {}))
console.log(sources)

Another javascript array alphabetical sorting hardtime

I have an array that looks like this, how can I sort it alphabetically without loosing the key?
var items = [
{ 11: 'Edward' },
{ 12: 'Sharpe' },
{ 13: 'Alvin' }
];
You can sort the items array using Object.values.
const items = [
{ 11: 'Edward' },
{ 12: 'Sharpe' },
{ 13: 'Alvin' }
];
items.sort((a, b) => Object.values(a)[0] > Object.values(b)[0]);
console.log(items);
If the objects have only one key, then you can use Object.keys to retrieve that key an then sort:
var items = [
{ '11': 'Edward' },
{ '12': 'Sharpe' },
{ '13': 'Alvin' }
];
items.sort(function(a, b) {
var akey = Object.keys(a) [0], // get a's key
bkey = Object.keys(b) [0]; // get b's key
return a[akey].localeCompare(b[bkey]); // compare the values using those keys
});
console.log(items);
By using Object.keys, since they only have one value we don't know, we can use the length property minus one to get the actual key reference.
var items = [
{ 11: 'Edward' },
{ 12: 'Sharpe' },
{ 13: 'Alvin' }
];
items.sort(function(a, b){
var c = Object.keys(a);
var d = Object.keys(b);
return a[c[c.length-1]] > b[d[d.length-1]] ? 1: -1;
}
)
console.log(items);

how to transform object with list of properties to array when Array.prototype.slice.call does not work?

This is working for list:
> Array.prototype.slice.call([1,2,3])
> [1, 2, 3]
How to create list from this type of data {1: "1", 2: "2", 3: "3"} ? Are there other methods than iterating object with for ?
the Array.prototype.slice.call() is not working here and gives []
This came from data = Object {0: Object, 1: Object, 2: Object, total : '29'} and then i delete data['total'] and need to access to slice, pop and other methods of Array
You could use the keys and map the values.
var o = {1: "1", 2: "2", 3: "3"},
a = Object.keys(o).map(function (k) {
return o[k];
});
console.log(a);
console.log(Array.prototype.slice.call({1: "1", 2: "2", 3: "3", length:5}));
The question arised, why Array.prototype.slice.call does not work. Basically because a length property is missing.
Only properties, which can be used as indices are used.
var o1 = {1: "1", 2: "2", 3: "3"},
o2 = {1: "1", 2: "2", 3: "3", length: 5},
o3 = {1: "1", 2: "2", 3: "3", abc: 42, length: 5},
o4 = {0: "0", 1: "1", 2: "2", 3: "3"};
o4.length=Object.keys(o4).length;
console.log(Array.prototype.slice.call(o1));
console.log(Array.prototype.slice.call(o2));
console.log(Array.prototype.slice.call(o3));
console.log(Array.prototype.slice.call(o4));
Note: Dynamic length of properties-in-object could be assigned using Object.keys(OBJECT). The cause of getting undefined in console is missing property at index 0
var list = [];
for (item in obj) {
list.push(obj[item]);
}
//use list.push(parseInt(obj[item])) for number array
You can also do the following if you want it straight
Object.values(obj);

Categories

Resources