Merge Array by one of its value - javascript

I want to filter from two different arrays based on following array named = timeArray
["13:37", "13:36", "13:35", "13:34", "13:33", "13:32"]
first array looks like this .. array1
[
[23323.25,23323.65,23313.25,23315.05,97,62,"13:36"],
[23315.05,23315.2,23314,23315,8,9,"13:37"]
]
second array looks like this .. array2
[
[23310,23310,23300,23300,0,0,"13:34"],
[23309.75,23343.1,23305,23323.25,0,0,"13:35"],
[23296.5,23310,23294.65,23309.8,0,0,"13:30"],
[23308.35,23310,23301,23306.15,0,0,"13:31"],
[23308,23309,23292.5,23299.55,0,0,"13:32"],
[23299.55,23310,23294.15,23310,0,0,"13:33"],
[23310,23310,23300,23300,0,0,"13:34"],
[23309.75,23343.1,23305,23324.65,0,0,"13:35"],
[23308,23309,23292.5,23299.55,0,0,"13:36"]
]
Based on Timearray elements, First should check array1 and then array 2 6th element and expected result should look like
[
[23308,23309,23292.5,23299.55,0,0,"13:32"],
[23299.55,23310,23294.15,23310,0,0,"13:33"],
[23310,23310,23300,23300,0,0,"13:34"],
[23309.75,23343.1,23305,23324.65,0,0,"13:35"],
[23323.25,23323.65,23313.25,23315.05,97,62,"13:36"],
[23315.05,23315.2,23314,23315,8,9,"13:37"]
]
I tried something like below
var finalarray = [];
for(var key in timeArray)
{
var timer = timeArray[key];
for(var key in array1)
{
arraytime1 = array1[key][6];
if(timer == arraytime1)
{
finalarray.push(arraytime1);
}
}
for(var key in array2)
{
arraytime2 = array2[key][6];
if(timer == arraytime2)
{
finalarray.push(arraytime2);
}
}
}
But "13:36" is added two times...Also if the element based on timerArray is not present it should be null... also is there any better way to do it ? I feel like it takes much resource to process... Thank you.

You could take an object for keeping the fist array for each time and map the result.
const
timeArray = ["13:37", "13:36", "13:35", "13:34", "13:33", "13:32"],
array1 = [[23323.25, 23323.65, 23313.25, 23315.05, 97, 62, "13:36"], [23315.05, 23315.2, 23314, 23315, 8, 9, "13:37"]],
array2 = [[23310, 23310, 23300, 23300, 0, 0, "13:34"], [23309.75, 23343.1, 23305, 23323.25, 0, 0, "13:35"], [23296.5, 23310, 23294.65, 23309.8, 0, 0, "13:30"], [23308.35, 23310, 23301, 23306.15, 0, 0, "13:31"], [23308, 23309, 23292.5, 23299.55, 0, 0, "13:32"], [23299.55, 23310, 23294.15, 23310, 0, 0, "13:33"], [23310, 23310, 23300, 23300, 0, 0, "13:34"], [23309.75, 23343.1, 23305, 23324.65, 0, 0, "13:35"], [23308, 23309, 23292.5, 23299.55, 0, 0, "13:36"]],
times = [array1, array2].reduce((r, array) => {
array.forEach(a => r[a[6]] ??= a)
return r;
}, {}),
result = timeArray
.sort()
.map(time => times[time] || [0, 0, 0, 0, 0, time]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

I believe this is what you want
const base = ["13:37", "13:36", "13:35", "13:34", "13:33", "13:32"]
const arrayA = [
[23323.25,23323.65,23313.25,23315.05,97,62,"13:36"],
[23315.05,23315.2,23314,23315,8,9,"13:37"]
]
const arrayB = [
[23310,23310,23300,23300,0,0,"13:34"],
[23309.75,23343.1,23305,23323.25,0,0,"13:35"],
[23296.5,23310,23294.65,23309.8,0,0,"13:30"],
[23308.35,23310,23301,23306.15,0,0,"13:31"],
[23308,23309,23292.5,23299.55,0,0,"13:32"],
[23299.55,23310,23294.15,23310,0,0,"13:33"],
[23310,23310,23300,23300,0,0,"13:34"],
[23309.75,23343.1,23305,23324.65,0,0,"13:35"],
[23308,23309,23292.5,23299.55,0,0,"13:36"]
]
// const expectedResult = [
// [23308,23309,23292.5,23299.55,0,0,"13:32"],
// [23299.55,23310,23294.15,23310,0,0,"13:33"],
// [23310,23310,23300,23300,0,0,"13:34"],
// [23309.75,23343.1,23305,23324.65,0,0,"13:35"],
// [23323.25,23323.65,23313.25,23315.05,97,62,"13:36"],
// [23315.05,23315.2,23314,23315,8,9,"13:37"]
//]
const res = base.sort().map(time => {
return arrayA.find(subArray => subArray[subArray.length - 1] === time)
|| arrayB.find(subArray => subArray[subArray.length - 1] === time)
|| null
});
console.log(res);

I would modify the arrays in the following format to obtain a much faster access:
{
"13:34": [23310,23310,23300,23300,0,0]
}
Then find the appropriate array for each time item.
Code:
const timeArray = ["13:37", "13:36", "13:35", "13:34", "13:33", "13:32"]
const array1 = [
[23323.25,23323.65,23313.25,23315.05,97,62,"13:36"],
[23315.05,23315.2,23314,23315,8,9,"13:37"]
]
const array2 = [
[23310,23310,23300,23300,0,0,"13:34"],
[23309.75,23343.1,23305,23323.25,0,0,"13:35"],
[23296.5,23310,23294.65,23309.8,0,0,"13:30"],
[23308.35,23310,23301,23306.15,0,0,"13:31"],
[23308,23309,23292.5,23299.55,0,0,"13:32"],
[23299.55,23310,23294.15,23310,0,0,"13:33"],
[23310,23310,23300,23300,0,0,"13:34"],
[23309.75,23343.1,23305,23324.65,0,0,"13:35"],
[23308,23309,23292.5,23299.55,0,0,"13:36"]
]
const values1 = {}
array1.forEach(item => {
values1[item[6]] = item
})
const values2 = {}
array2.forEach(item => {
values2[item[6]] = item
})
const result = []
timeArray.sort().forEach(time => {
let itemResult = [0,0,0,0,0,0, time]
if (values1[time]) {
itemResult = values1[time]
} else if (values2[time]) {
itemResult = values2[time]
}
result.push(itemResult)
})
console.log(result)

in my opinion you can do like this
var finalarray = [];
for(var key in timeArray)
{
var timer = timeArray[key];
for(var key in array2)
{
arraytime2 = array2[key][6];
if(timer == arraytime2)
{
finalarray[arraytime2]=array2[key];
}
}
for(var key in array1)
{
arraytime1 = array1[key][6];
if(timer == arraytime1)
{
finalarray[arraytime1]=array1[key];
}
}
}

It is possible to use Map collection to have O(1) while mapping the items. So we can sort timeArray and then just map() items:
const unique_1 = new Map(array1.map(s => [s[6], s]));
const unique_2 = new Map(array2.map(s => [s[6], s]));
const result = timeArray
.sort()
.map(time => unique_1.get(time) || unique_2.get(time));
An example:
const timeArray = ["13:37", "13:36", "13:35", "13:34", "13:33", "13:32"]
const array1 = [
[23323.25, 23323.65, 23313.25, 23315.05, 97, 62, "13:36"],
[23315.05, 23315.2, 23314, 23315, 8, 9, "13:37"]
]
const array2 = [
[23310, 23310, 23300, 23300, 0, 0, "13:34"],
[23309.75, 23343.1, 23305, 23323.25, 0, 0, "13:35"],
[23296.5, 23310, 23294.65, 23309.8, 0, 0, "13:30"],
[23308.35, 23310, 23301, 23306.15, 0, 0, "13:31"],
[23308, 23309, 23292.5, 23299.55, 0, 0, "13:32"],
[23299.55, 23310, 23294.15, 23310, 0, 0, "13:33"],
[23310, 23310, 23300, 23300, 0, 0, "13:34"],
[23309.75, 23343.1, 23305, 23324.65, 0, 0, "13:35"],
[23308, 23309, 23292.5, 23299.55, 0, 0, "13:36"]
]
const unique_1 = new Map(array1.map(s => [s[6], s]));
const unique_2 = new Map(array2.map(s => [s[6], s]));
const result = timeArray
.sort()
.map(time => unique_1.get(time) || unique_2.get(time));
console.log(result)

Related

dynamically get columns from 2D array

I have a 2D array of row,through which i want get the column coordinates/information just like i got for the row(rowArr2D)
So,in my Column(colArr2D) i'm just getting all 4th position values in the array since i passed have oRowCount in the function
my goal is to get all columns respectively.
Example:
Row:[ [ 0, 1, 2, 3, 4, 5, 6 ], [ 0, 1, 2, 3, 4, 5, 6 ], [ 0, 1, 2, 3, 4, 5, 6 ], [ 0, 1, 2, 3, 4, 5, 6 ] ]
Columns: [[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3]]
mockTable = { // mocking the portions of my code
GetRowsCount : () => 4,
GetRow: (x) => ({
GetCellsCount : () => 7,
GetCell : (x) => x
})
}
CTable_prototype_GetTableMapping = function(currentTable)
{
//get row information
let oRowCount = currentTable.GetRowsCount();
const rowArr2D = Array(oRowCount);
for (let i = 0; i < oRowCount; i++) {
//get cell information and cell count
let oRow = currentTable.GetRow(i);
let oCellCount = oRow.GetCellsCount();
rowArr2D[i] = Array(oCellCount);
for (let j = 0; j < oCellCount; j++) {
//get cell content
let oCell = oRow.GetCell(j);
rowArr2D[i][j] = oCell;
}
}
// get column information
const colArr2D = (array, colCount) => {
const result = [];
array.forEach(e => {
result.push(e[colCount]);
});
console.log(result);
return result;
};
colArr2D(rowArr2D, oRowCount);
return rowArr2D
console.log(rowArr2D);
};
const theArray = CTable_prototype_GetTableMapping(mockTable);
console.log("full 2D array", theArray)
Give this a try
const colArr2D = (array) =>
array[0].map((a, i) =>
array.map(b => b[i])
);
const arr = [[1,2,3],[4,5,6],[7,8,9]];
console.log(colArr2D(arr))

javascript convert for loop filter on index to functional programming

I have got the following code that returns an object based on a filter
i want to convert this to functional programming using map, filter.
var records_object = {
"record": [
"analog",
"laser",
"monochrome",
"digital"
],
"vcd": [
12,
3,
6,
0
],
"dvd": [
1,
0,
0,
16
]
}
var arr_idx = [];
for (i = 0; i < records_object.record.length; i++) {
if (records_object.record[i].match(/digital/i) != null||
records_object.record[i].match(/analog/i) != null) {
arr_idx.push(i);
}
}
for (el in records_object) {
records_object[el] = records_object[el].filter(function (x, i) {
return arr_idx.indexOf(i) != -1;
});
}
console.log(records_object);
so far i was able to do this , now i am stuck
const getIndex = (data) => {
return data.record
.map((e, i) =>
e.includes("analog") || e.includes("digital") ? i : undefined
)
.filter((x) => x !== undefined);
};
You can do this,
var records_object = {
"record": [
"analog",
"laser",
"monochrome",
"digital"
],
"vcd": [
12,
3,
6,
0
],
"dvd": [
1,
0,
0,
16
]
}
let arrayIndexes = records_object.record.map((item, index) => {
if(item.match(/digital/i) != null || item.match(/analog/i) !== null) {
return index;
}
}).filter(item => item !== undefined);
let newObject = Object.keys(records_object).reduce((prev, key) => {
prev[key] = records_object[key].filter((item, index) => arrayIndexes.includes(index));
return prev;
}, {});
console.log(newObject);
The problem was with filter.
when you are running map it returns array [0, undefined, undefined, 3] and that array is being filtered and as you are using filter(x => x), this will iterate through the returned array and remove all the falsy values and return the resulting array.
In [0, undefined, undefined, 3]'s case, only 3 is the truthy value and that's why you are getting only [3] as 0 too is falsy.
You can modify your code slightly to get this resolved.
var records_object = {
record: ["analog", "laser", "monochrome", "digital"],
vcd: [12, 3, 6, 0],
dvd: [1, 0, 0, 16],
};
const getIndex = (data) => {
return data.record
.map((e, i) =>
e.includes("analog") || e.includes("digital") ? i : undefined
)
.filter((x) => x !== undefined);
};
console.log(getIndex(records_object));
Here is the solution using reduce and filter function. I've saved the result in new object.
var records_object = {
"record": [
"analog",
"laser",
"monochrome",
"digital"
],
"vcd": [
12,
3,
6,
0
],
"dvd": [
1,
0,
0,
16
]
};
const matchByString = ['analog', 'digital'];
const isMatch = (el, stringElements) => stringElements.some((strEl) => el.match(new RegExp(strEl, 'i')) != null);
const filterByIndex = records_object.record.reduce((acc, el, index) => isMatch(el, matchByString) ? [...acc, index] : acc, [])
const result = {};
Object.keys(records_object).forEach(i => result[i] = records_object[i].filter((el, i) => filterByIndex.includes(i)));
console.log(result)

Get specific data from array and put in other array

I have this result in javascript and i want to get data that has value more that 3 and i want to put in other array .
"availableDates": {
"2020-01-24": 1,
"2020-01-23": 3,
"2020-01-22": 2,
"2020-01-21": 1,
"2020-01-25": 4,
"2021-01-07": 1
}
I group here :
const formattedDate = x.reduce((acc,el) => {
const date = el.split(" ")[0];
acc[date] = (acc[date] || 0) + 1;
return acc;
}, {});
now I want to put in other array all that date that has value more than 3 . For example
newarray = [ "2020-01-23", "2020-01-25" ]
Why don't use a simple .filter() over keys of "availableDates":
const grouped = {
"availableDates": {
"2020-01-24": 1,
"2020-01-23": 3,
"2020-01-22": 2,
"2020-01-21": 1,
"2020-01-25": 4,
"2021-01-07": 1
}
};
const newArray = Object.keys(grouped.availableDates).filter((key) => grouped.availableDates[key] >= 3);
console.log(newArray);
You can simply use a for...in loop to iterate over object keys and filter them:
const data = {
"2020-01-24": 1,
"2020-01-23": 3,
"2020-01-22": 2,
"2020-01-21": 1,
"2020-01-25": 4,
"2021-01-07": 1
};
const reducer = (obj, val) => {
const result = [];
for(key in obj) {
if(obj[key] >= val)
result.push(key);
};
return result;
};
console.log(reducer(data, 3));
You could have something like this. I write a complete bunch of the code to make you able to copy/past to test
var availableDates = new Array()
var availableDates = {
"2020-01-24": 1,
"2020-01-23": 3,
"2020-01-22": 2,
"2020-01-21": 1,
"2020-01-25": 4,
"2021-01-07": 1
}
var results = new Array();
for (date in availableDates){
if (availableDates[date] >= 3){
results.push(date)
}
}
console.log(results)

BASIC Javascript array function, issue is known but I cannot fathom a solution

In the below function I am attempting to get an output which resembles this:
[[1,1,1,1],[2,2,2], 4,5,10,[20,20], 391, 392,591].
I can see that the problem I have embedded is that I am always adding the temp array with a push to the functions return, as a result, all of the individual numbers apart from the last number in the for each function are being pushed into the target array with the array object also.
I feel as though I need a further conditonal check but for the life of me I am unable to come up with solution which works.
Any suggestions would be much appreciated.
const sortme = (unsortedArr)=> {
let tempArr = [];
let outputArr = [];
const reorderedArr = unsortedArr.sort((a,b) => a-b);
reorderedArr.forEach((number, i) => {
if ((i === 0) || (reorderedArr[i] === reorderedArr[i-1])) {
tempArr.push(number);
}
else {
outputArr.push(tempArr);
tempArr = [];
tempArr.push(number);
}
})
outputArr.push(tempArr[0]);
return outputArr;
}
const unsortedArr = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];
sortme(unsortedArr);
i would make a deduped copy and .map() it to transform the values into arrays containing values from the original ( sorted ) array that you get using a .forEach :
const unsortedArr = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
const sortMe = (arr) => {
arr = arr.sort((a, b) => a - b);
// a short way to dedupe an array
// results in : 1, 2, 4, 5, 10, 20, 391, 392, 591
let dedupe = [...new Set(arr)];
let tmpArr;
return dedupe.map(e => {
tmpArr = []; // empty tmpArr on each iteration
// for each element of the deduped array, look for matching elements in the original one and push them in the tmpArr
arr.forEach(a => {
if (a === e)
tmpArr.push(e);
})
if(tmpArr.length === 1)
return tmpArr[0]; // in case you have [4] , just return the 4
else
return tmpArr; // in case you have [1,1,1,1]
// shorthand for the if/else above
// return tmpArr.length === 1 ? tmpArr[0] : tmpArr;
});
}
const result = sortMe(unsortedArr);
console.log(result);
This should work (using reduce):
const unsortedArr = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];
let lastValue = null;
var newArr = unsortedArr.sort((a,b) => a-b).reduce((acc, value) => {
if (acc.length == 0 || ((acc.length > 0 || !acc[acc.length-1].length) && lastValue !== value)) {
acc.push(value);
} else if (acc.length > 0 && lastValue === value) {
acc[acc.length-1] = (acc[acc.length-1].length ? acc[acc.length-1].concat([value]): [value, value]);
}
lastValue = value;
return acc;
}, []);
console.log(newArr);
And another approach, just for fun:
const unsortedArr = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];
var arr = unsortedArr.sort((a,b) => a-b).reduce((acc, value) => {
if (acc.length > 0 && acc[acc.length-1].includes(value)) {
acc[acc.length-1].push(value);
} else {
acc.push([value])
}
return acc;
}, []).map((v) => v.length > 1 ? v: v[0]);
console.log(arr);
I hope the below one is quite simple;
function findSame(pos, sortedArr){
for(let i =pos; i<sortedArr.length; i++){
if(sortedArr[i] !== sortedArr[pos]){
return i
}
}
}
function clubSameNumbers(unsortedArr){
let sortedArr = unsortedArr.sort((a,b)=>a-b)
//[ 1, 1, 1, 1, 2, 2, 2, 4, 5, 10, 20, 20, 391, 392, 591 ]
let result = []
for(let i = 0; i < sortedArr.length; i = end){
let start = i
var end = findSame(i, sortedArr)
let arr = sortedArr.slice(i, end)
arr.length > 1 ? result.push(arr) : result.push(...arr)
}
return result
}
console.log(clubSameNumbers([1,2,4,591,392,391,2,5,10,2,1,1,1,20,20]))
//[ [ 1, 1, 1, 1 ], [ 2, 2, 2 ], 4, 5, 10, [ 20, 20 ], 391, 392, 591 ]

easiest way to transform array into matrix using java-script

I have written down my first JavaScript code to do some dynamic rendering in a webpage:
var c_names = ["Canada", "USA", "israel"]
var c_ids = [1, 2, 3]
var c_domaain = ["www.canada.com", "www.usa.com", "www.israel.com"]
var data_1 = []
var C_data = [
['Country', 'ids', 'Domain']
]
var x = 1
for (i = 0; i == 3; i++) {
var x = x + 1
data_1.push(c_name[x], c_ids[x], c_domain[x])
for (i = 0; i < c_name.length; i++) {
C_data.push(data_1)
}
}
console.log(C_data)
I'm expecting this output:
data = [ ['Country', 'ids', 'Domain'],
['USA', 1, 'www.usa.com'],
['Canada', 2, 'www.usa.com'],
['Israel', 3, 'www.usa.com'],
]
Iterate over one of the arrays and then append the respective items.
var names = ["Canada", "USA", "israel"]
var ids = [1, 2, 3]
var domains = ["www.canada.com", "www.usa.com", "www.israel.com"]
var data = [
["Country", "ID", "Domain"]
]
names.forEach ((name, idx) => {
data.push ([ name, ids [idx], domains [idx]]);
});
console.log(data)
You could take the array in one array and iterate the outer and the the inner array while respecting the index.
var c_names = ["Canada", "USA", "israel"],
c_ids = [1, 2, 3],
c_domaain = ["www.canada.com", "www.usa.com", "www.israel.com"],
c_data = ['Country', 'ids', 'Domain'],
result = [c_names, c_ids, c_data].reduce(function (r, a) {
a.forEach(function (b, i) {
r[i] = r[i] || [];
r[i].push(b);
});
return r;
}, []);
result.unshift(c_data);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
var c_names = ["Canada", "USA", "israel"]
var c_ids = [1, 2, 3]
var c_domaain = ["www.canada.com", "www.usa.com", "www.israel.com"]
var C_data = [
['Country', 'ids', 'Domain']
]
var i = -1;
while ( c_names[++i] ) {
C_data.push( [ c_names[i], c_ids[i], c_domaain[i]] );
}
console.log(C_data)
var c_names = ["Canada","USA","israel" ];
var c_ids = [1,2,3];
var c_domaain = ["www.canada.com","www.usa.com","www.israel.com"];
var data_1 = [];
var C_data = ['Country', 'ids', 'Domain'];
var x = 1;
for(var i = 0; i < c_names.length; i++){
data_1.push(new Array(C_data[i], c_names[i], c_domaain[i]));
};
console.log(data_1);
This is the output of your code which is wrong:
[ [ "Country", "ids","Domain"],
[ "Canada", 1, "Country"],
[ "USA", 2, "ids" ],
[ "israel", 3, "Domain"]
]

Categories

Resources