I have an array that is currently sorted by the first value:
[ [ 'a', 3 ],
[ 'c', 3 ],
[ 'd', 1 ],
[ 'e', 2 ],
[ 'f', 1 ],
[ 'g', 1 ],
[ 'i', 7 ],
[ 'l', 3 ],
[ 'o', 2 ],
[ 'p', 2 ],
[ 'r', 2 ],
[ 's', 3 ],
[ 't', 1 ],
[ 'u', 2 ],
[ 'x', 1 ] ]
I would like to sort the digits in descending order to get:
[ [ 'i', 7 ],
[ 'a', 3 ],
[ 'c', 3 ],
[ 'l', 3 ],
[ 's', 3 ],
[ 'e', 2 ],
[ 'o', 2 ] ......]
Use Array.sort([compareFunction])
function comparator(a, b) {
if (a[1] > b[1]) return -1
if (a[1] < b[1]) return 1
return 0
}
myArray = myArray.sort(comparator)
edit for comment:
Here is a jslint showing it in action:
https://jsfiddle.net/49ed0Lj4/1/
The sort method in Array
var arr = [
['a', 3],
['c', 3],
['d', 1],
['e', 2],
['f', 1],
['g', 1],
['i', 7],
['l', 3],
['o', 2],
['p', 2],
['r', 2],
['s', 3],
['t', 1],
['u', 2],
['x', 1]
];
arr.sort(function(a, b) {
return b[1] - a[1]
})
Maybe you need to sort by both the English letters and number. You can change the callback function to do this.
Related
Although it is a common problem but I couldn't find any lead to get the desired result. So here is the problem. I have the following array:
[
[ 'a' ]
[ 'a', 'b' ]
[ 'a', 'c' ]
[ 'a', 'c', 'd' ]
[ 'a', 'c', 'd', 'e' ]
]
And what I want as an end result is an object like this:
{
a: {
b: {},
c: { d: { e: {} } }
}
}
I don't understand which approach would be better to get this result and how to achieve it.
You need a double reduce, one for the outer array and one for the keys and the nesting objects.
var data = [['a'], ['a', 'b'], ['a', 'c'], ['a', 'c', 'd'], ['a', 'c', 'd', 'e']],
result = data.reduce((r, keys) => {
keys.reduce((o, k) => o[k] = o[k] || {}, r);
return r;
}, {});
console.log(result);
Here are the variables:
let linked = {
related: [
[0, 'a', 'b'],
[0, 'c', 'd', 'e', 'f', 'g'],
[0, "s"],
[0, 'd'],
[0, 'g', 'n', 'h']
]
}
let hold = [{
0: 4, // 0 represents [0,'a','b']
1: 3 // 1 represents [0,'c','d','e','f','g']
},
{
3: 2, // 3 represents [0,'d']
4: 6 // 4 represents [0,'g','n', 'h']
}
];
The hold array contains two objects and each object's property represents index of link.related .
The problem is I want to add values of each hold object property to the first element of linked.related.
So the result should be:
let linked = {
related: [
[4, 'a', 'b'],
[3, 'c', 'd', 'e', 'f', 'g'],
[0, "s"],
[2, 'd'],
[6, 'g', 'n', 'h']
]
}
So I want to sum values of hold with the first element of linked.related
You can do it in 2 forEach loops
hold.forEach(x => {
Object.keys(x).forEach (y => {
linked.related[y][0] += x[y]
});
});
let linked = {
related: [
[0, 'a', 'b'],
[0, 'c', 'd', 'e', 'f', 'g'],
[0, "s"],
[0, 'd'],
[0, 'g', 'n', 'h']
]
}
let hold = [{
0: 4,
1: 3
},
{
3: 2,
4: 6
}
];
hold.forEach(x => {
Object.keys(x).forEach (y => {
linked.related[y][0] += x[y]
});
});
console.log(linked.related);
You could iterate hold and get the entries for the update.
var linked = { related: [[0, 'a', 'b'], [0, 'c', 'd', 'e', 'f', 'g'], [0, "s"], [0, 'd'], [0, 'g', 'n', 'h']] },
hold = [{ 0: 4, 1: 3 }, { 3: 2, 4: 6 }];
hold.forEach(o => Object.entries(o).forEach(([i, v]) => linked.related[i][0] += v));
console.log(linked);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use forEach and Object.entries
let linked = {related: [[0, 'a', 'b'],[0, 'c', 'd', 'e', 'f', 'g'],[0, "s"],[0, 'd'],[0, 'g', 'n', 'h']]}
let hold =[{0: 4, 1:3},{3: 2, 4:6}]
hold.forEach(v => {
Object.entries(v).forEach(([k, v]) => {
linked.related[k][0] += v
})
})
console.log(linked)
I have two arrays
One is:
[ [ 2, 'c' ],
[ 2, 'e' ],
[ 3, 'a' ],
[ 3, 'b' ] ]
and another is :
[ 3, [ 1, 'g' ], [ 2, [ 1, 'd' ], [ 1, 'f' ] ] ]
how can I concatenate both and get output like
[ [ 2, 'c' ],
[ 2, 'e' ],
[ 3, 'a' ],
[ 3, 'b' ],
[ 3, [ 1, 'g' ], [ 2, [ 1, 'd' ], [ 1, 'f' ] ] ]
var arr1 = [ [ 2, 'c' ],
[ 2, 'e' ],
[ 3, 'a' ],
[ 3, 'b' ] ];
var arr2 = [ 3, [ 1, 'g' ], [ 2, [ 1, 'd' ], [ 1, 'f' ] ] ];
arr1.push(arr2);
Have you tried using the spread operator? Please be aware that it's not supported in IE.
const x =
[ [ 2, 'c' ],
[ 2, 'e' ],
[ 3, 'a' ],
[ 3, 'b' ] ];
const y = [ 3, [ 1, 'g' ], [ 2, [ 1, 'd' ], [ 1, 'f' ] ] ];
const z = [...x, y];
console.log(z);
You could wrap the additional array in extra brackets for use with Array#concat.
var a = [[2, 'c'], [2, 'e'], [3, 'a'], [3, 'b']],
b = [3, [1, 'g'], [2, [1, 'd'], [1, 'f']]];
console.log(a.concat([b]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
concat will merge two arrays into one array without changing the original arrays
Code
const x =
[ [ 2, 'c' ],
[ 2, 'e' ],
[ 3, 'a' ],
[ 3, 'b' ] ]
const y = [ 3, [ 1, 'g' ], [ 2, [ 1, 'd' ], [ 1, 'f' ] ] ];
const z = x.concat([y])
Example
const x = [
[2, 'c'],
[2, 'e'],
[3, 'a'],
[3, 'b']
]
const y = [3, [1, 'g'],
[2, [1, 'd'],
[1, 'f']
]
];
const z = x.concat([y])
console.log(z)
If the following is my array of question, how can I get the value in the position [0][2][1] by supplying the index values in an array eg:answer = [0, 2, 1].
var question = [
[
['x', 'x', 'x'],
['x', 'x', 'x'],
['x', 'x', 'x']
],
[
['x', 'x', 'x'],
['x', 'x', 'x'],
['x', 'x', 'x']
],
[
['x', 'x', 'x'],
['x', 'x', 'x'],
['x', 'x', 'x']
]
];
var answer = [0,2,1];
question.get(answer); // Is there a way like this?
Is there way like question.get(answer) or question.get([0, 2, 1])?
There's a hard coded way:
question[answer[0]][answer[1]][answer[2]];
or for any length of a array or nested array:
var question = [
[
['x', 'x', 'x'],
['x', 'x', 'x'],
['x', 'x', 'x']
],
[
['x', 'x', 'x'],
['x', 'x', 'x'],
['x', 'x', 'x']
],
[
['x', 'x', 'x'],
['x', 'x', 'x'],
['x', 'x', 'x']
]
];
var answer = [0,2,1];
var getanswer= function(answerinput,questioninput){
var val = questioninput;
answerinput.forEach(function(item){
val = val[item];
});
return val;
}
console.log(getanswer(answer,question));
Let's have some fun...
Object.prototype.getNestedValue = function(...a) {
return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]];
};
var question = [
[
['1', '2', '3'],
['4', '5', '6'],
['7', '8', '9']
],
[
['a', 'b', 'c'],
['d', 'e', 'f'],
['g', 'h', 'i']
],
[
[':', ',', '?'],
['#', '$', '%'],
['+', '!', '&']
]
];
console.log(question.getNestedValue(...[0,2,1]));
console.log(question.getNestedValue(...[1,2,0]));
console.log(question.getNestedValue(...[2,0,1]));
You could use Array#reduce, because you can use the question array as input and get the value as result by iterating the given answer array.
var question = [[['000', '001', '002'], ['010', '011', '012'], ['020', '021', '022']], [['100', '101', '102'], ['110', '111', '112'], ['120', '121', '122']], [['200', '201', '202'], ['210', '211', '212'], ['220', '221', '222']]],
answer = [0, 2, 1],
getItem = function (array, path) {
return path.reduce(function (a, p) { return a[p]; }, array);
};
console.log(getItem(question, answer));
ES6
var question = [[['000', '001', '002'], ['010', '011', '012'], ['020', '021', '022']], [['100', '101', '102'], ['110', '111', '112'], ['120', '121', '122']], [['200', '201', '202'], ['210', '211', '212'], ['220', '221', '222']]],
answer = [0, 2, 1],
getItem = (array, path) => path.reduce((a, p) => a[p], array);
console.log(getItem(question, answer));
Traversal of an object is easy, but I found it hard to figure out the traversal paths for myself.
For example, here we have data like below:
data = {
a: 'A',
b: {
d: [
'F',
'G'
],
e: 'D'
},
c: 'C'
}
I want to output the traversal paths like this:
['a']
['b', 'd', 0]
['b', 'd', 1]
['b', 'e']
['c']
How do I write the algorithm?
function rec(currentObject, path) {
if (typeof currentObject !== "string" && currentObject.length) {
for (var i = 0; i < currentObject.length; i += 1) {
rec(currentObject[i], path.concat(i));
}
} else if (typeof currentObject === "object") {
for (var item in currentObject) {
rec(currentObject[item], path.concat(item))
}
} else {
console.log(path);
}
}
rec(data, []);
Output
[ 'a' ]
[ 'b', 'd', 0 ]
[ 'b', 'd', 1 ]
[ 'b', 'e' ]
[ 'c' ]