How to convert this array to an array of objects? - javascript

This is my array:
[
['x', 1],
['y', 2],
['z', 3],
['F', "_180"],
['x', 1],
['y', 2],
['z', 3],
['t', 4]
['F', "_360"],
['x', 1],
['y', 2],
['z', 3],
['t', 4],
['m', 5]
['F', "_480"],
]
This is what I want to achieve:
[{
profile_180: {
x: 1,
y: 2,
z: 3
}
}, {
profile_360: {
x: 1,
y: 2,
z: 3,
t: 4
}
}, {
profile_480: {
x: 1,
y: 2,
z: 3
t: 4,
m: 5
}
}]
How do I get this?

data = [
['x', 1],
['y', 2],
['z', 3],
['F', "_180"],
['x', 1],
['y', 2],
['z', 3],
['t', 4],
['F', "_360"],
['x', 1],
['y', 2],
['z', 3],
['t', 4],
['m', 5],
['F', "_480"],
];
var result = {};
var current = {};
data.forEach(function(row) {
if (row[0] == 'F') {
result['profile' + row[1]] = current;
current = {};
} else {
current[row[0]] = row[1];
}
});
console.log(result);
<!-- results pane console output; see http://meta.stackexchange.com/a/242491 -->
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

You can do it by,
var res = [], tmp = {}, obj = {};
x.forEach(function(itm,i) {
if(itm[0] !== "F"){
tmp[itm[0]] = itm[1];
} else {
obj["profile_" + itm[1]] = tmp;
res.push(obj);
tmp = {}, obj ={};
}
});
where x is the array that contains the data.

try this
var obj = [
['x', 1],
['y', 2],
['z', 3],
['F', "_180"],
['x', 1],
['y', 2],
['z', 3],
['t', 4],
['F', "_360"],
['x', 1],
['y', 2],
['z', 3],
['t', 4],
['m', 5],
['F', "_480"],
];
var output = [];
var tmpArr = {};
obj.forEach(function(value,index){
console.log(value);
if (value[0] != 'F' )
{
tmpArr[value[0]] = value[1];
}
else
{
var profileValue = "Profile_" + value[1];
var tmpObj = {};
tmpObj[profileValue] = tmpArr;
output.push( tmpObj );
tmpArr = {};
}
});
document.body.innerHTML += JSON.stringify(output,0,4);

Related

JavaScript How to replace first element of an array with each element of another array

I have two arrays and I need to replace the first element of the first array with each elements of the second array:
let firstArray = [
[1, 'a', 'hello'],
[2, 'b', 'world'],
[3, 'c', 'other'],
...
];
let secondArray = [1, 3, 7, ...];
// Result:
// [
// [1, 'a', 'hello'],
// [3, 'b', 'world'],
// [7, 'c', 'other'],
// ...
// ]
I tried doing something like this:
firstArray.map(f => {
secondArray.forEach(s => {
f.splice(0, 1, s);
})
})
But this replace the first element only with the last element of second array
Use .map to transform an array into another:
const firstArray = [
[1, 'a', 'hello'],
[2, 'b', 'world'],
[3, 'c', 'other'],
];
const secondArray = [1, 3, 7];
const transformed = firstArray.map(([, ...rest], i) => [secondArray[i], ...rest]);
console.log(transformed);
Another option:
const firstArray = [
[1, 'a', 'hello'],
[2, 'b', 'world'],
[3, 'c', 'other'],
];
const secondArray = [1, 3, 7];
const transformed = firstArray.map((item, i) => [secondArray[i]].concat(item.slice(1)));
console.log(transformed);
You could assign the array to a new array and take the new value to a specified index.
const
firstArray = [[1, 'a', 'hello'], [2, 'b', 'world'], [3, 'c', 'other']],
secondArray = [1, 3, 7],
result = firstArray.map((a, i) => Object.assign([], a, { 0: secondArray[i] }));
console.log(result);

Have two javascipt arrays to combine into one object and add up values

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)

Lots of Loops, Lots of Questions

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 to pivot a javascript array

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;
})

a function to search array

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.

Categories