I have 3 two dimensional arrays as given below which are series data to plot lines on a graph with the key being the timestamp.
const arr1 = [[1641013200000,1881],[1643691600000,38993],[1646110800000,41337],[1648785600000,78856],[1651377600000,117738],[1654056000000,119869],[1656648000000,157799],[1659326400000,196752],[1662004800000,199061],[1664596800000,237034],[1667275200000,239153],[1669870800000,269967]]
const arr2 = [[1641013200000,1302],[1643691600000,3347],[1646110800000,4754],[1648785600000,6948],[1651377600000,9725],[1654056000000,11314],[1656648000000,13787],[1659326400000,16666],[1662004800000,18370],[1664596800000,20876],[1667275200000,22384],[1669870800000,23560]]
const arr3 = [[1643691600000,67350],[1648785600000,134700],[1651377600000,202148],[1654056000000,202270],[1656648000000,269843],[1659326400000,337346],[1662004800000,337470],[1664596800000,404861],[1667275200000,404889],[1669870800000,472239]]
I want to plot another series line which gives the cumulative total of all three arrays values
(Note: if a timestamp is not present in either of the arrays, add the previous index value)
const totalArray = [
[1641013200000,3183],[1643691600000, 109690],[1646110800000, 113441],[1648785600000, 220504],
[1651377600000, 329611],[1654056000000, 333453],[1656648000000, 441429],[1659326400000, 550764],
[1662004800000, 554901],[1664596800000, 662771],[1667275200000, 666426],[1669870800000, 765766]
]
I have tried this, but some values are incorrect due to the timestamp not being present in either one
Approach:
const arr1 = [
[1641013200000, 1881],
[1643691600000, 38993],
[1646110800000, 41337],
[1648785600000, 78856],
[1651377600000, 117738],
[1654056000000, 119869],
[1656648000000, 157799],
[1659326400000, 196752],
[1662004800000, 199061],
[1664596800000, 237034],
[1667275200000, 239153],
[1669870800000, 269967]
];
const arr2 = [
[1641013200000, 1302],
[1643691600000, 3347],
[1646110800000, 4754],
[1648785600000, 6948],
[1651377600000, 9725],
[1654056000000, 11314],
[1656648000000, 13787],
[1659326400000, 16666],
[1662004800000, 18370],
[1664596800000, 20876],
[1667275200000, 22384],
[1669870800000, 23560]
];
const arr3 = [
[1643691600000, 67350],
[1648785600000, 134700],
[1651377600000, 202148],
[1654056000000, 202270],
[1656648000000, 269843],
[1659326400000, 337346],
[1662004800000, 337470],
[1664596800000, 404861],
[1667275200000, 404889],
[1669870800000, 472239]
];
const calculateTotal = () => {
var ret;
for (let a3 of arr3) {
var index = arr1.map(function(el) {
return el[0];
}).indexOf(a3[0]);
console.log(index);
if (index === -1) {
ret = arr1[index][0];
console.log(ret);
}
}
let unsortedArr = arr1.concat(arr2, arr3);
var sortedArray = unsortedArr.sort((a, b) => a[0] - b[0]);
var added = addArray(sortedArray);
console.log("Curent Output: " + JSON.stringify(added));
}
const addArray = (tuples) => {
var hash = {},
keys = [];
tuples.forEach(function(tuple) {
var key = tuple[0],
value = tuple[1];
if (hash[key] === undefined) {
keys.push(key);
hash[key] = value;
} else {
hash[key] += value;
}
});
return keys.map(function(key) {
return ([key, hash[key]]);
});
}
calculateTotal();
Is it possible to achieve this?
In your code there is this:
if (index === -1) {
ret = arr1[index][0];
But that assignment will fail as arr1[-1] is not defined.
Then when you do:
let unsortedArr = arr1.concat(arr2, arr3);
...you end up with an array that does not have the knowledge to use default values (from a previous index) when any of the three arrays has a "missing" time stamp.
I would suggest this approach:
Collect all the unique timestamps (from all arrays) into a Map, and associate arrays to each of those keys: these will be empty initially.
Populate those arrays with the timestamps from the original arrays
Get the sorted list of entries from that map
Fill the "gaps" by carrying forward values to a next array when the corresponding slot is undefined. At the same time sum up these values for the final output.
Here is an implementation:
function mergeArrays(...arrays) {
const map = new Map(arrays.flatMap(arr => arr.map(([stamp]) => [stamp, []])));
arrays.forEach((arr, i) => {
for (const [timeStamp, value] of arr) {
map.get(timeStamp)[i] = value;
}
});
const state = Array(arrays.length).fill(0);
return Array.from(map).sort(([a], [b]) => a - b).map(([timeStamp, arr], i) =>
[timeStamp, state.reduce((sum, prev, j) => sum + (state[j] = arr[j] ?? prev), 0)]
);
}
// Example run
const arr1 = [[1641013200000,1881],[1643691600000,38993],[1646110800000,41337],[1648785600000,78856],[1651377600000,117738],[1654056000000,119869],[1656648000000,157799],[1659326400000,196752],[1662004800000,199061],[1664596800000,237034],[1667275200000,239153],[1669870800000,269967]];
const arr2 = [[1641013200000,1302],[1643691600000,3347],[1646110800000,4754],[1648785600000,6948],[1651377600000,9725],[1654056000000,11314],[1656648000000,13787],[1659326400000,16666],[1662004800000,18370],[1664596800000,20876],[1667275200000,22384],[1669870800000,23560]];
const arr3 = [[1643691600000,67350],[1648785600000,134700],[1651377600000,202148],[1654056000000,202270],[1656648000000,269843],[1659326400000,337346],[1662004800000,337470],[1664596800000,404861],[1667275200000,404889],[1669870800000,472239]];
const result = mergeArrays(arr1, arr2, arr3);
console.log(result);
I have this array,
var arr = [["present",["John","Josh","Jay"]],["absent",["May","Mary","Mary Jane"]]];
var arr2 = [["J",["John","Josh","Jay"]],["M",["May","Mary","Mary Jane"]]];
And I want to get the data[0] of the array that have value of "Mary".
So in my example, value that I will get is "absent".
I want also to get the index of the array arr2 that have value of "Josh".
So in my second array, value that I will get is 0.
If possible to use underscore js, we can use it.
I tried to use _.contains() but failed.
Also these array is used in knockout js.
One other way of doing this job could be as follows;
var a1 = [["present",["John","Josh","Jay"]],["absent",["May","Mary","Mary Jane"]]],
a2 = [["J",["John","Josh","Jay"]],["M",["May","Mary","Mary Jane"]],["S",["Sally","Sam","Sammy Davis"]]],
getStatus = (a,n) => a.find(e => e[1].indexOf(n) !== -1)[0],
getIndex = (a,n) => a.findIndex(e => e[1].indexOf(n) !== -1);
console.log(getStatus(a1,"Mary"));
console.log(getIndex(a2,"Sammy Davis"));
var arr = [["present",["John","Josh","Jay"]],["absent",["May","Mary","Mary Jane"]]];
var arr2 = [["J",["John","Josh","Jay"]],["M",["May","Mary","Mary Jane"]]];
arr.forEach(function(e,i,a){
if(e[1].indexOf("Mary")>-1){
console.log(e[0])
}
});
arr2.forEach(function(e,i,a){
if(e[1].indexOf("Josh")>-1){
console.log(e[0])
}
});
First using filter() and second findIndex()
var arr = [["present",["John","Josh","Jay"]],["absent",["May","Mary","Mary Jane"]]];
var result1 = arr.filter(x => x[1].indexOf("Mary") !== -1)[0][0];
console.log(result1); // absent
var arr2 = [["J",["John","Josh","Jay"]],["M",["May","Mary","Mary Jane"]]];
var result2 = arr.findIndex(x => x[1].indexOf("Josh") !== -1);
console.log(result2); // 0
If your data set isn't really huge you can store two map objects in memory to quickly access values. Note that this won't work for duplicate names.
The benefit of this approach is that you only have to loop through each array once. If you use any method based on indexOf, you'll loop through your data every time you retrieve a value.
var arr = [["present",["John","Josh","Jay"]],["absent",["May","Mary","Mary Jane"]]];
var arr2 = [["J",["John","Josh","Jay"]],["M",["May","Mary","Mary Jane"]]];
var makeKeyMap = function(arr) {
return arr.reduce(function(map, data) {
data[1].forEach(function(key) {
map[key] = data[0];
});
return map;
}, {});
};
var makeIndexMap = function(arr) {
return arr.reduce(function(map, data, index) {
data[1].forEach(function(key) {
map[key] = index;
});
return map;
}, {});
};
var arrMap = makeKeyMap(arr);
var arr2Map = makeIndexMap(arr2);
console.log(arrMap["Mary"]);
console.log(arr2Map["Josh"]);
Edit: a performance test
var myTestData = createTestData();
var randomNameToFind = (function() {
var namesToFind = ["Aileen","Christina","Donna","Judith","Mandy","Sandra","Dawn","Tracey","Mhairi","Victoria","Carolyn","Gayle","Maria","Valerie"];
return function() {
return namesToFind[Math.floor(Math.random() * namesToFind.length)];
}
}());
console.log("Finding the number index for a random name out of 800 names, 10000 times:");
console.time("using index of approach");
var usingIndexOf = (a,n) => a.findIndex(e => e[1].indexOf(n) !== -1);
var results = [];
for (var i = 0; i < 10000; i += 1) {
results.push(usingIndexOf(myTestData, randomNameToFind()));
}
console.timeEnd("using index of approach");
console.time("using map approach");
var makeIndexMap = function(arr) {
return arr.reduce(function(map, data, index) {
data[1].forEach(function(key) {
map[key] = index;
});
return map;
}, {});
};
var myMap = makeIndexMap(myTestData);
results = [];
for (var j = 0; j < 10000; j += 1) {
results.push(myMap[randomNameToFind()]);
}
console.timeEnd("using map approach");
console.log("index map size: " + sizeof(myMap) + " bytes");
// Random data generation code below
function createTestData() {
var names = ["Nicola","Karen","Fiona","Susan","Claire","Sharon","Angela","Gillian","Julie","Michelle","Jacqueline","Amanda","Tracy","Louise","Jennifer","Alison","Sarah","Donna","Caroline","Elaine","Lynn","Margaret","Elizabeth","Lesley","Deborah","Pauline","Lorraine","Laura","Lisa","Tracey","Carol","Linda","Lorna","Catherine","Wendy","Lynne","Yvonne","Pamela","Kirsty","Jane","Emma","Joanne","Heather","Suzanne","Anne","Diane","Helen","Victoria","Dawn","Mary","Samantha","Marie","Kerry","Ann","Hazel","Christine","Gail","Andrea","Clare","Sandra","Shona","Kathleen","Paula","Shirley","Denise","Melanie","Patricia","Audrey","Ruth","Jill","Lee","Leigh","Catriona","Rachel","Morag","Kirsten","Kirsteen","Katrina","Joanna","Lynsey","Cheryl","Debbie","Maureen","Janet","Aileen","Arlene","Zoe","Lindsay","Stephanie","Judith","Mandy","Jillian","Mhairi","Barbara","Carolyn","Gayle","Maria","Valerie","Christina","Marion","Nicola","Karen","Susan","Claire","Fiona","Angela","Sharon","Gillian","Julie","Jennifer","Michelle","Louise","Lisa","Amanda","Donna","Tracy","Alison","Elaine","Jacqueline","Sarah","Caroline","Elizabeth","Laura","Lynn","Deborah","Lesley","Margaret","Joanne","Pauline","Lorraine","Carol","Kirsty","Yvonne","Lorna","Emma","Lynne","Tracey","Heather","Catherine","Pamela","Helen","Linda","Jane","Anne","Kerry","Suzanne","Wendy","Victoria","Diane","Mary","Dawn","Clare","Gail","Paula","Ann","Shona","Hazel","Christine","Andrea","Samantha","Marie","Lynsey","Sandra","Denise","Lee","Kelly","Gayle","Debbie","Jill","Kathleen","Patricia","Joanna","Catriona","Shirley","Ruth","Zoe","Leigh","Rachel","Melanie","Kirsteen","Aileen","Christina","Janet","Katrina","Stephanie","Audrey","Kirsten","Arlene","Maureen","Morag","Marion","Mhairi","Allison","Cheryl","Maria","Kim","Anna","Lindsay","Rebecca","Katherine","Mandy","Nicola","Karen","Claire","Angela","Fiona","Susan","Jennifer","Julie","Gillian","Michelle","Sharon","Sarah","Louise","Donna","Laura","Amanda","Alison","Lisa","Caroline","Kirsty","Jacqueline","Elaine","Lesley","Lynn","Deborah","Elizabeth","Joanne","Emma","Tracy","Lorraine","Lynne","Margaret","Heather","Carol","Lorna","Pauline","Kelly","Helen","Catherine","Linda","Victoria","Suzanne","Kerry","Pamela","Lee","Wendy","Jane","Yvonne","Tracey","Anne","Clare","Mary","Diane","Christine","Lynsey","Samantha","Shona","Andrea","Marie","Gail","Melanie","Dawn","Ann","Paula","Jill","Ruth","Leigh","Hazel","Debbie","Joanna","Denise","Lindsay","Gayle","Patricia","Catriona","Kathleen","Sandra","Leanne","Stephanie","Rachel","Katrina","Shirley","Kirsteen","Janet","Arlene","Zoe","Jillian","Anna","Judith","Mhairi","Natalie","Audrey","Carolyn","Morag","Aileen","Cheryl","Rebecca","Allison","Barbara","Mandy","Claire","Nicola","Karen","Angela","Gillian","Fiona","Jennifer","Laura","Susan","Julie","Michelle","Lisa","Sharon","Louise","Sarah","Tracy","Donna","Kelly","Kirsty","Amanda","Alison","Joanne","Caroline","Emma","Jacqueline","Elaine","Elizabeth","Lynne","Lesley","Deborah","Kerry","Victoria","Carol","Catherine","Lynn","Pauline","Margaret","Lorna","Lynsey","Lorraine","Linda","Suzanne","Tracey","Heather","Yvonne","Jane","Dawn","Mary","Helen","Anne","Wendy","Lee","Pamela","Jill","Lindsay","Clare","Christine","Diane","Leigh","Samantha","Shona","Joanna","Ruth","Debbie","Gail","Marie","Andrea","Paula","Kathleen","Catriona","Katrina","Denise","Melanie","Ann","Sandra","Gayle","Hazel","Jillian","Stephanie","Rachel","Kim","Natalie","Katherine","Patricia","Leanne","Cheryl","Mhairi","Morag","Arlene","Zoe","Kathryn","Aileen","Ashley","Judith","Anna","Frances","Janet","Lucy","Vicky","Christina","Kirsten","Rebecca","Nicola","Claire","Laura","Karen","Michelle","Louise","Jennifer","Fiona","Lisa","Gillian","Angela","Julie","Susan","Sarah","Kelly","Donna","Sharon","Emma","Caroline","Alison","Joanne","Tracy","Kirsty","Lynne","Amanda","Elaine","Jacqueline","Lesley","Kerry","Elizabeth","Lynn","Margaret","Deborah","Catherine","Heather","Lorna","Yvonne","Carol","Lorraine","Suzanne","Lynsey","Victoria","Helen","Linda","Pauline","Dawn","Anne","Jane","Tracey","Clare","Mary","Diane","Jill","Denise","Lee","Leanne","Christine","Shona","Pamela","Samantha","Paula","Joanna","Debbie","Stacey","Hazel","Cheryl","Lindsay","Gail","Rachel","Marie","Ann","Catriona","Andrea","Ruth","Kathryn","Katrina","Mhairi","Wendy","Leigh","Gayle","Melanie","Sandra","Stephanie","Anna","Jillian","Amy","Carolyn","Patricia","Carrie","Natalie","Kathleen","Lyndsey","Ashley","Rebecca","Vicky","Christina","Lindsey","Katherine","Arlene","Sara","Laura","Claire","Nicola","Lisa","Louise","Michelle","Fiona","Karen","Gillian","Jennifer","Emma","Angela","Susan","Kelly","Julie","Donna","Sarah","Kirsty","Sharon","Joanne","Amanda","Tracy","Alison","Elizabeth","Caroline","Elaine","Jacqueline","Lynne","Leanne","Deborah","Lesley","Lorraine","Victoria","Lynn","Pamela","Kerry","Lynsey","Lorna","Carol","Margaret","Heather","Helen","Catherine","Suzanne","Tracey","Yvonne","Cheryl","Linda","Pauline","Debbie","Jane","Dawn","Clare","Lindsay","Mary","Shona","Anne","Rachel","Jill","Christine","Natalie","Samantha","Diane","Lee","Wendy","Joanna","Paula","Marie","Ann","Denise","Catriona","Gayle","Hazel","Kathleen","Stacey","Gail","Ashley","Andrea","Ruth","Anna","Jillian","Leigh","Katrina","Stephanie","Mhairi","Katherine","Sandra","Lyndsey","Christina","Lucy","Patricia","Carrie","Rebecca","Kathryn","Lyndsay","Melanie","Amy","Sara","Arlene","Kirsten","Laura","Claire","Lisa","Nicola","Louise","Karen","Fiona","Jennifer","Michelle","Emma","Sarah","Gillian","Kelly","Susan","Angela","Donna","Kirsty","Julie","Pamela","Joanne","Caroline","Amanda","Tracy","Sharon","Lynne","Elaine","Deborah","Jacqueline","Alison","Lynsey","Victoria","Kerry","Leanne","Lorraine","Lesley","Elizabeth","Lorna","Catherine","Lynn","Suzanne","Heather","Helen","Lindsay","Margaret","Clare","Cheryl","Debbie","Pauline","Dawn","Carol","Mary","Natalie","Linda","Jane","Diane","Stacey","Carrie","Yvonne","Rebecca","Christine","Marie","Charlene","Rachel","Anne","Tracey","Jill","Samantha","Ashley","Paula","Joanna","Stephanie","Andrea","Shona","Denise","Anna","Hazel","Katrina","Ruth","Gayle","Lee","Sara","Catriona","Kathryn","Leigh","Mhairi","Wendy","Amy","Jillian","Katherine","Gail","Linsey","Christina","Lucy","Melanie","Sandra","Ann","Kathleen","Shelley","Kirsten","Kim","Lyndsey","Laura","Claire","Lisa","Nicola","Emma","Louise","Jennifer","Michelle","Sarah","Fiona","Karen","Gillian","Kirsty","Donna","Kelly","Pamela","Susan","Julie","Angela","Amanda","Lynsey","Sharon","Lynne","Deborah","Joanne","Victoria","Caroline","Alison","Leanne","Gemma","Elaine","Jacqueline","Lesley","Elizabeth","Lorraine","Kerry","Heather","Debbie","Catherine","Lynn","Lorna","Tracy","Suzanne","Yvonne","Cheryl","Natalie","Margaret","Lindsay","Diane","Helen","Pauline","Ashley","Rachel","Clare","Carol","Christine","Linda","Dawn","Rebecca","Stephanie","Jill","Tracey","Jane","Stacey","Paula","Shona","Anna","Charlene","Anne","Marie","Catriona","Samantha","Joanna","Ruth","Andrea","Mary","Denise","Kim","Mhairi","Hazel","Lauren","Amy","Kathryn","Carrie","Lyndsey","Lucy","Gail","Katherine","Christina","Linsey","Wendy","Katrina","Kimberley","Ann","Lee"];
var nameMap = names.reduce((map, n) => {
map[n[0]] = map[n[0]] || [];
map[n[0]].push(n);
return map;
}, {});
var testData = Object.keys(nameMap)
.sort()
.reduce((res, k) => {
res.push([k, nameMap[k]]);
return res;
}, []);
return testData;
};
<script src="http://code.stephenmorley.org/javascript/finding-the-memory-usage-of-objects/sizeof.compressed.js"></script>