I have this javascript array:
[['a', 'x', 1],
['a', 'y', 2],
['b', 'x', 3],
['b', 'z', 4],
['c', 'y', 5],
['c', 'z', 6]]
How do I pivot it to something like below with the 2nd column ('x', 'y', 'z') from above going across.
[['a', 1, 2, null],
['b', 3, null, 4],
['c', null, 5, 6]]
EDIT:
Sorry I was unclear. The answers so far seem to be referencing a static length/value for x, y, z. The array will be dynamic and can have anything in the 2nd column (ex. 't','u','v','w' instead of 'x','y','z'). I think I need to fill the array up first with nulls for all the possible combinations and then push in the values.
Thanks..
Going by Fabricio's comment, here is how you can accomplish something similar:
var result = {};
for(var i=0;i< basearray.length;i++){
if(!result[basearray[i][0]]){
result[basearray[i][0]]={};
}
result[basearray[i][0]][basearray[i][1]]=basearray[i][2];
}
Note that this returns an object or hashmap, not strictly an array, but the data is more organised and it can easily be turned into an array if you so wish. Here is a demonstration (check your console).
By adding this code:
var count=0;
for(var key in result){
result[count]=[];
result[count][0]=key;
result[count][1]=result[key].x||null;
result[count][2]=result[key].y||null;
result[count][3]=result[key].z||null;
count++;
}
your result object now simulates both structures, your original array of arrays, and the suggested key value pairs. You can see the results here: http://jsfiddle.net/9Lakw/3/
Here is what result looks like:
{
"a":{
"x":1,
"y":2
},
"b":{
"x":3,
"z":4
},
"c":{
"y":5,
"z":6
},
"0":[
"a",
1,
2,
null
],
"1":[
"b",
3,
null,
4
],
"2":[
"c",
null,
5,
6
]
}
Here's how I'd do it, with arrays and null fillers as in the question. This assumes that coords for given points always come in succession.
var arr = [['a', 'x', 1],
['a', 'y', 2],
['b', 'x', 3],
['b', 'z', 4],
['c', 'y', 5],
['c', 'z', 6]];
var aux = {
x: 1,
y: 2,
z: 3
},
output = [],
lastItem,
currItem;
for (var i = 0; i < arr.length; i++) {
currItem = arr[i];
if (currItem[0] !== lastItem) {
lastItem = currItem[0];
output.push([lastItem, null, null, null]);
}
output[output.length-1][aux[currItem[1]]] = currItem[2];
}
console.log(output); //[["a", 1, 2, null], ["b", 3, null, 4], ["c", null, 5, 6]]
Fiddle
Are you sure that's the format you want? It seems more sensible to get:
{
a: {x: 1, y: 2},
b: {x: 3, z: 4},
c: {y: 5, z: 6}
}
Which you can get from:
var results = {};
data.forEach(function(el) {
var name = el[0];
var prop = el[1];
var value = el[2];
results[name] = results[name] || {};
results[name][prop] = value;
})
Related
I want to write a code in javascript to convert a nested array in to a nested object. The point is every single elements in the nested array would be an array itself, so should convert to a nested object:
Examples:
[['a', 1], ['b', 2], ['c', [['d', 4]]]] => { a: 1, b: 2, c: { d: 4 } }
[['a', 1], ['b', 2], ['c', [['d', [['e', 5], ['f', 6]]]]]]
=> { a: 1, b: 2, c: { d: { e: 5, f: 6 } } }
I tried to go with this concept:
define a function to iterate over the base array. for every single element, it will make a key:value for the object. if the value is an array, the function will call itself.
but Actually I dont know how to write it.
const nestedArrayToObject = function (arr) {
let obj = {};
for (let i = 0; i < arr.length; i++) {
let key = arr[i][0];
let val = arr[i][1];
if (!Array.isArray(val)) {
obj[key] = val;
} else {
nestedArrayToObject(val); ???
}
}
return obj;
};
You can use Object.fromEntries to convert an array of key-value pairs to an object. For each value that is also an array, recursively call the conversion function.
function convert(arr) {
return Object.fromEntries(arr.map(([k, v]) =>
[k, Array.isArray(v) ? convert(v) : v]));
}
console.log(convert([['a', 1], ['b', 2], ['c', [['d', 4]]]]));
console.log(convert([['a', 1], ['b', 2], ['c', [['d', [['e', 5], ['f', 6]]]]]]));
Hi and I'm new to JavaScripts and hopefully anyone of you would help me to figure out. Thanks
My question is how to write a function that expects an array which could contain strings and/or numbers (as well as finite levels of nested arrays of strings and/or numbers), and returns an object which shows the total number of occurences of each unique values.
function functionName() {
const inputArray = [ 2, 5, 2, 'a', [ 'd', 5, 2, ['b', 1], 0 ], 'A', 5, 'b', 2, 'd' ];
const outputResult = functionName(inputArray);
}
The key in the object is the unique values found in the array, and the value for each key is the number of occurences for each unique key
The expected result I want is :
{
'2': 4,
'5': 3,
'a': 1,
'd': 2,
'b': 2,
'1': 1,
'0': 1,
'A': 1,
}
You can try:
const inputArray = [ 2, 5, 2, 'a', [ 'd', 5, 2, ['b', 1], 0 ], 'A', 5, 'b', 2, 'd' ];
const result = inputArray.flat(Infinity).reduce((acc, item) => (acc[item] = (acc[item] || 0) + 1, acc), {})
console.log(result)
You need to recursiely get occurences of each value, like implemented in calculateOccurences:
const calculateOccurences = function(inputArray, outputResult){
inputArray.forEach(function(value){
if(typeof(value)==='number' || typeof(value)==='string'){
outputResult[value] = outputResult[value] ? outputResult[value]+1 : 1;
}else if (Array.isArray(value)){
calculateOccurences(value, outputResult);
}
})
}
const inputArray = [ 2, 5, 2, 'a', [ 'd', 5, 2, ['b', 1], 0 ], 'A', 5, 'b', 2, 'd' ];
const outputResult = {}
calculateOccurences(inputArray, outputResult );
console.log(outputResult);
Assuming that numbers would be present in type number and not string or that 2 and '2' should be treated the same while calulating occurences.
In this case it's easier if you convert array into string.
var input = [ 2, 5, 2, 'a', [ 'd', 5, 2, ['b', 1], 0 ], 'A', 5, 'b', 2, 'd' ];
//conver intput into string and replace ',' characters
var stringInput = input.toString().replace(/,/g,'');
var output = {};
//counting
for (var i = 0; i < stringInput.length; i++) {
var element = stringInput[i];
output[element] = output[element] ? output[element] + 1 : 1;
}
console.log(output);
I want to combine the following two same-size arrays:
var depts = [ 'A', 'D', 'M', 'G', 'D', 'B', 'D', 'A', 'A' ];
var cnts = [ 3, 7, 15, 2, 9, 5, 12, 4, 8 ];
Into an object like this, note cnts are the totals for each depts:
{A: 15, D: 19, M: 15, G: 2, B: 5}
Normally I perform data manipulation prior to web site integration however I want begin performing it in JavaScript. Some code that roughly mimics what I'm trying to do.
var obj = {};
for(var i = 0; i < depts.length; i++)
{
console.log(depts[i], cnts[i]);
obj[depts[i]] = cnts[i]; // <- don't know how to increment assignment
}
console.log(obj);
This code creates an object however does not sum cnts by depts:
{A: 8, D: 12, M: 15, G: 2, B: 5}
Just add a check if the property exist and assign zero. Later add the value to it.
var depts = ['A', 'D', 'M', 'G', 'D', 'B', 'D', 'A', 'A'],
cnts = [3, 7, 15, 2, 9, 5, 12, 4, 8],
obj = {};
for (var i = 0; i < depts.length; i++) {
if (!obj[depts[i]]) obj[depts[i]] = 0; // use an initial value
obj[depts[i]] += cnts[i]; // add value
}
console.log(obj);
Try this
const depts = [ 'A', 'D', 'M', 'G', 'D', 'B', 'D', 'A', 'A' ];
const cnts = [ 3, 7, 15, 2, 9, 5, 12, 4, 8 ];
let obj = {};
// loop over the first array, if not already in obj, put a zero before adding
depts.forEach((dept,i) => obj[dept] = (obj[dept] || 0) + cnts[i])
console.log(obj);
var depts = [ 'A', 'D', 'M', 'G', 'D', 'B', 'D', 'A', 'A' ];
var cnts = [ 3, 7, 15, 2, 9, 5, 12, 4, 8 ];
const lkp = depts.reduce((lkp, cur, i) => {
return {
...lkp,
[cur]: ~~lkp[cur] + cnts[i]
}
}, {})
console.log (lkp)
I've written this code. It seems to run correctly through the first set of nested for loops. When I put in debugger above the final for loop, it will return the correct thing for me (and if I want to return newArray, it will return). What am I doing wrong?
I want it to loop through the letterSplit array I've made of the input, then loop through the values array and find the corresponding value, and push that corresponding value into the newArray. This works so far with 1 letter.
BUT I also want it to work for multiple letters, so that if someone puts in "cat", it will add them all up into a new array "total". That is what I was trying to do with the last for loop. Suggestions? Ideas? Do you see a misplaced word or character somewhere?
var scrabble = function (letter) {
var newLetter = letter.toLowerCase();
var letterSplit = newLetter.split(" ");
var newArray = [];
var stupidArray = [];
var total = 0;
var values = [["a", 1], ["b", 3], ["c", 3], ["d", 2], ["e", 1], ["f", 4], ["g", 2], ["h", 4], ["i", 1], ["j", 8], ["k", 5], ["l", 1], ["m", 3], ["n", 1], ["o", 1],
["p", 3], ["q", 10], ["r", 1], ["s", 1], ["t", 1], ["u", 1], ["v", 4], ["w", 4], ["x", 8], ["y", 4], ["z", 10]];
for (var i=0; i < letterSplit.length; i++) {
for (var i=0; i < values.length; i++) {
if (values[i][0] === letterSplit[0]) {
newArray.push(values[i][1]);
stupidArray += letterSplit.splice(0,1);
}
}
}
for (var i=0; i < newArray.length; i++) {
total += i;
}
var result = total.toString();
return total;
};
Using an Object as a lookup for the letter value would probably be simpler/more sensible. Something like this.
Javascript
var values = {
a: 1,
b: 3,
c: 3,
d: 2,
e: 1,
f: 4,
g: 2,
h: 4,
i: 1,
j: 8,
k: 5,
l: 1,
m: 3,
n: 1,
o: 1,
p: 3,
q: 10,
r: 1,
s: 1,
t: 1,
u: 1,
v: 4,
w: 4,
x: 8,
y: 4,
z: 10
};
function scrabble(word) {
return word.toLowerCase().split('').reduce(function (acc, letter) {
if (values.hasOwnProperty(letter)) {
acc += values[letter];
}
return acc;
}, 0);
}
console.log(scrabble('cat'));
Output
5
On jsFiddle
Your code corrected
Javascript
var scrabble = function (letter) {
var letterSplit = letter.toLowerCase().split(''),
total = 0,
values = [
['a', 1],
['b', 3],
['c', 3],
['d', 2],
['e', 1],
['f', 4],
['g', 2],
['h', 4],
['i', 1],
['j', 8],
['k', 5],
['l', 1],
['m', 3],
['n', 1],
['o', 1],
['p', 3],
['q', 10],
['r', 1],
['s', 1],
['t', 1],
['u', 1],
['v', 4],
['w', 4],
['x', 8],
['y', 4],
['z', 10]
],
i,
j;
for (i = 0; i < letterSplit.length; i++) {
for (j = 0; j < values.length; j++) {
if (values[j][0] === letterSplit[i]) {
total += values[j][1];
break;
}
}
}
return total;
};
console.log(scrabble('cat'));
On jsFiddle
How can I search for an element within a nested array. Following is what the array looks like
arr = [
["choice1", ['a', [2, 4]], ['b', [1, 3, 4]], ['c', [3, 4]]],
["choice2", ['b', [1, 4]], ['c', [1, 3]]],
["choice3", ['b', [1, 2, 4]], ['c', [1, 2, 3, 4]]]
]
if 'a' is equal to '2' then the following function has to return "choice1" and "choice3" in the 'result':
function arraySearch(arr, a) {
var result = [];
for(var i = 0; i < arr.length; i++) {
// compare each arr[i] with 'a' for the very first occurrence, and move the next array
if(arr[i].search(a)){
result.concat(arr[0]);
}
}
return result;
}
Please help. Many thanks in advance.
something like
arr = [
["choice1", ['a', [2, 4]], ['b', [1, 3, 4]], ['c', [3, 4]]],
["choice2", ['b', [1, 4]], ['c', [1, 3]]],
["choice3", ['b', [1, 2, 4]], ['c', [1, 2, 3, 4]]]
];
find = function(arr, a) {
var found = [];
var foundCurrent;
// for each 'choice'
for (var choice = 0; choice < arr.length; choice++) {
foundCurrent = false;
// look at each entry in the array that is arr[current][1]
for (var entry = 1; entry < arr[choice].length; entry++) {
// search these for the value
if (arr[choice][entry][1].indexOf(a) != -1) {
if (!foundCurrent) {
found[found.length] = arr[choice][0];
}
foundCurrent = true;
}
}
}
return found;
};
find(arr, 2);
>> [choice1, choice3]
It's not clear to me exactly what you need.
If you want to know whether an array contains an element, use Array.indexOf.