Javascript Sort a hash by values in array - javascript

I have a hash like below
a ={
0: [0, "A9"],
2: [0, "A9.4"],
8: [0, "A9.1"],
6: [1, "A9.5"],
5: [0, "A9.2"],
7: [2, "A9.3"]
};
I need a sorted array corresponding to the second element of the array of every Value.
i.e if my array is in the form of a = {key: [value_1_integer, value_2_string]}
I need to sort my hash by value_2_string so result array is
result = [0, 8, 5, 7, 2, 6]

You can apply Array#sort on the keys with a callback which takes the second elements of the property for sorting.
var object = { 0: [0, "A9"], 2: [0, "A9.4"], 8: [0, "A9.1"], 6: [1, "A9.5"], 5: [0, "A9.2"], 7: [2, "A9.3"] },
keys = Object.keys(object).sort(function (a, b) {
return object[a][1].localeCompare(object[b][1]);
});
console.log(keys);

Related

Splice strange thing

I have next code
function doneOrNot(board) {
console.log(board);
let blockNum = [...(board.splice(0, 2))];
return blockNum;
}
console.log(doneOrNot([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))
On first console.log I got
(3) [Array(3), Array(3), Array(3)]
0: (3) [7, 8, 9]
length: 1
[[Prototype]]: Array(0)
(Length 3 or 1???)
And on second:
(2) [Array(3), Array(3)]
0: (3) [1, 2, 3]
1: (3) [4, 5, 6]
length: 2
[[Prototype]]: Array(0)
But why array of arrays have changed before (after?) split?
Array splice method, mutates original array and returns removed items.
const arr = [1, 2, 3];
// now arr has 3 elements
const removed_items = arr.splice(0, 2);
// Now removed_items will have [1, 2]
// and arr will have [3]
By the time When you expand on 'console log' in dev tools, the arr has only 1 element. That is reason you are seeing the 1 element.

Generate new order of numbers from array

I'm currently trying to generate a new order of numbers from a current array with numbers from 1 - 10.
For example, I have arrary like this:
data = [
{
0: 1,
1: 2,
2: 3,
3: 4,
4: 5,
5: 6
},
{
0: 1,
1: 2,
2: 3,
3: 4,
4: 5,
5: 8
}
]
And i'm trying to generate a new order from this array from numbers from 1 - 10.
For example:
I want it to generate a new order like this:
0: 1,
1: 2,
2: 3,
3: 4,
4: 5,
5: 7 (The new number)
Where it checks the order of the array, and make a new order with numbers from 1 - 10
First thing to do is to create an object with the total values. We can accomplish this by looping over each object in the array and add each value to a new object. For this we can use the reduce method on the data array.
After that loop over the object with the totals and divide each value with the amount of objects that are present in the data array.
Use Math.round() to round each value to the nearest whole number.
const data = [{
0: 1,
1: 2,
2: 3,
3: 4,
4: 5,
5: 6
},
{
0: 1,
1: 2,
2: 3,
3: 4,
4: 5,
5: 8
}
];
function getDataTotal(data) {
const totalObject = data.reduce((total, curObj) => {
for (const key of Object.keys(curObj)) {
total[key] = total[key]
? total[key] + curObj[key]
: curObj[key];
}
return total;
}, {});
const averageObject = {};
for (const [key, value] of Object.entries(totalObject)) {
averageObject[key] = Math.round(value / data.length);
}
return averageObject;
}
const averageObject = getDataTotal(data);
console.log(averageObject);
Make sure you have the same keys on both objects.
const data = [
{0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6},
{0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 8},
]
getAverageValueOfMappingElements() {
const keys = Object.keys(data[0])
return [...keys].map(key => {
return (data[0][key] + data[1][key]) / 2
})
}

How can I convert multidimensional array into 2 dimensions array?

Given multidimensional array (of any size and depth):
const multidimensionalArray = [1, [2, [3, [4, [5]]]], [6], [7, [8], [9]]];
I need to convert it into 2 dimensions array following example below (the idea is that each nested value should be converted into an array of all parents + this value).
Expected 2 dimensions array :
const twoDimensionsArray = [
[1],
[1, 2],
[1, 2, 3],
[1, 2, 3, 4],
[1, 2, 3, 4, 5],
[1, 6],
[1, 7],
[1, 7, 8],
[1, 7, 9],
];
Could you please help me to solve the problem?
A recursive call for each nested array ought to do the trick.
NOTE: The following may not be complete for your use case - your data needs to be in a specific order for this to work - but I think this should be clean enough as an example:
const customFlatten = (arr, parents = [], output = []) => {
for (const item of arr) {
// If not an array...
if (!Array.isArray(item)) {
parents.push(item) // update parents for recursive calls
output.push(parents.slice(0)) // add entry to output (copy of _parents)
// If an array...
} else {
customFlatten(item, parents.slice(0), output) // recursive call
}
}
return output
}
console.log(customFlatten([1, [2, [3, [4, [5]]]], [6], [7, [8], [9]]]))

How to extract multiple columns from a two dimension array?

Could I have some guidance on how to extract multiple columns from a two-dimensional array like the below using JavaScript?
Array = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
];
the simple methods I've seen so far using forEach or map will allow extraction of ONE column at a time, is there a way to nest it somehow to extract whichever column index one desire?
Let's say the desire output column is 1,2 and 4.
Output = [
[1, 2, 4],
[5, 6, 8],
[9,10,12],
];
EDIT:
Another problem I need to resolve is how to remove a row if it's Array[i][1]=0 or empty.
Let say we have extra array elements...
Array = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
[13,0,15,16],
[17, ,19,20],
[21,22,23,24],
];
The desired output is now...
Output = [
[1, 2, 4],
[5, 6, 8],
[9,10,12],
[21,22,24],
];
You can .map() each row in arr to a new array which you can obtain by using an inner .map() on an array of columns/indexes which you wish to obtain. The inner map will map each index to its associated value from the row, giving you the values at each column for each row.
See example below:
const arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
];
const cols = [1, 2, 4];
const res = arr.map(r => cols.map(i => r[i-1]));
console.log(res);
Further details:
As you mentioned the first map exposes each inner array inside of arr to the inner mapping function:
cols.map(i => r[i-1])
This mapping function will loop through the indexes defined inside of cols and transform them into a new value. For example, say you're r is the second array:
[5, 6, 7, 8]
Performing cols.map(...) will loop over each element (denoted by i in the callback function) in [1, 2, 4]. For each element, we "transform" it into a new element:
i = 1
r = [5, 6, 7, 8]
new value: r[1-1] = 5
Next iteration we look at the next value in cols:
i = 2
r = [5, 6, 7, 8]
new value: r[2-1] = 6
Lastly, we look at the final value in cols:
i = 4
r = [5, 6, 7, 8]
new value: r[4-1] = 8
So the mapping function produces a new array which transforms the values from cols [1, 2, 4], into the values at those indexes in the current row to be [5, 6, 8]. This occurs for each inner array / row, producing the final result.
EDIT
As per your edit, you can apply the same logic from above to get your arrays with only the columns you desire. Once you have done that you can use .filter() to keep only the rows which have a truthy value in the second column. Keeping all the arrays with truthy values in the second column will remove the arrays with non-truthy values in the second column (falsy values) from your resulting array. 0 and undefined are both flasy values, so they are not kept.
See example below:
const arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
[13,0,15,16],
[17, ,19,20],
[21,22,23,24],
]
const cols = [1, 2, 4];
const col = 2;
const res = arr.filter(r => r[col-1]).map(r => cols.map(i => r[i-1]));
console.log(res);
If you have multiple columns you want to ignore, you can use .every() to ensure each (ie: every) column contains a truthy value. If they all do, then .every() will return true, keeping the column, otherwise, it will return false, removing the column:
const arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
[13,0,15,16],
[ ,17,19,20],
[21,22,23,24],
]
const cols = [1, 2, 4];
const col = [1, 2];
const res = arr.filter(r => col.every(c => r[c-1])).map(r => cols.map(i => r[i-1]));
console.log(res);
You can approach it the below given way. The solution is using the index parameter available in filter method .
Array.filter(currElem,index,array)
Since array is 0-indexed ,so I created the array with index you want in the data as [0,1,3] . You need to pass the data array and index array to the function .
var array = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
];
var arrIndex = [0,1,3];
function extractData(arr,indexArr) {
return arr.map(obj => {
return obj.filter((ob,index) => {
if(indexArr.includes(index)){return ob}
})
})
}
console.log(extractData(array,arrIndex));

Convert an Array to unique values only while maintaining the correct sequence

I have the following code:
function uniteUnique(arr) {
//Create a single Array of value
arr = arguments[0].concat(arguments[1], arguments[2]);
//Reduce the Array to unique values only
arr = arr.reduce((pre, curr) => {
//Some function to reduce values
});
return arr;
}
uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);
The goal is to produce a single Array containing only unique values while maintaining the order.
Currently it returns:
[1, 3, 2, 5, 2, 1, 4, 2, 1]
I'm wanting to reduce this to:
[1, 3, 2, 5, 4]
You can use Set for that:
function uniteUnique(...args) {
return [...new Set([].concat(...args))];
}
var u = uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);
console.log(u);
It maintains insertion order, and by nature only contains unique values.
In ES5 you could do it by maintaining the used values as properties of a temporary object, while building the result array:
function uniteUnique(/* args */) {
return [].concat.apply([], arguments).reduce(function (acc, v) {
if (!acc[0][v]) acc[0][v] = acc[1].push(v); // assigns new length, i.e. > 0
return acc;
}, [ Object.create(null), [] ])[1];
}
var u = uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);
console.log(u);
You can use the Set object since it already keeps your values unique in one object:
const mySet = new Set([1, 3, 2, 5, 2, 1, 4, 2, 1]);
// returns: Set { 1, 3, 4, 5 };
const arrayUniques = [...mySet];
console.log(arrayUniques);
// returns: [1, 3, 4, 5];

Categories

Resources