Set First Value as Key in Javascript Array - javascript

Creating an array based off selected DataTables Rows
$('#savenlp').click(recordjourney);
function recordjourney() {
var data = table.rows(['.selected']).data().toArray();
console.log( (data) );
console.log( JSON.stringify(data) );
}
data returns
0 : (8) ["Which", "TitleCase", "QuestionWord", "", "", "", "", ""]
JSON.stringify(data) returns
[["baseball","Noun","Singular","","","","",""]]
This information is dynamically generated, so I am just looking to take the first value (in this case baseball) and turn it into something like
"baseball": [
"Noun",
"Singular"
]
I can return the first value (the key I want using)
alert(data[0][0]);
I am much more adept in PHP but I am learning javascript/jquery more and more.
It is my understanding javascript does not have associative arrays, so I am a bit confused as to how to generate this.

const data = [
["baseball","Noun","Singular","","","","",""],
["baseballs","Noun","","Plural","","","","",]
];
const mappedData = data.reduce((acc, row) => { acc[row.shift()] = row.filter(d => d !== ''); return acc; }, {});
console.log(mappedData);

We can use object destructuring and spread operators for ease of use.
In the example below, the key will be the first item and all the rest items will be placed in the newData variable
const data = [["baseball","Noun","Singular","","","","",""]];
const [key, ...newData] = data[0]
// if you want the new data to not have empty entries, simple apply the filter
const newDataFiltered = newData.filter(item => !!item)
const objWithEmpty = {[key]: newData}
const objWithoutEmpty = {[key]: newDataFiltered}
console.log(objWithEmpty, objWithoutEmpty)
For multiple arrays inside the outer array, just enclose the whole logic inside a for loop
const data = [
["baseball","Noun","Singular","","","","",""],
["baseball1","Noun1","Singular1","","","","",""],
["baseball2","Noun2","Singular2","","","","",""]
];
const objWithEmpty = {}
const objWithoutEmpty = {}
data.forEach((array) => {
const [key, ...newData] = array
// if you want the new data to not have empty entries, simple apply the filter
const newDataFiltered = newData.filter(item => !!item)
objWithEmpty[key] = newData
objWithoutEmpty[key] = newDataFiltered
})
console.log(objWithEmpty, objWithoutEmpty)

Simply extract the desired values from data and put them into an object formatted as you like:
const data = [["baseball","Noun","Singular","","","","",""]];
const firstArr = data[0];
const transformedFirstObject = {
[firstArr[0]]: [firstArr[1], firstArr[2]],
};
console.log(transformedFirstObject);
But it's pretty weird to have an object with only one property like that. If your data might have more than one sub-array in it and you want to turn the array of arrays into an array of objects, use map:
const data = [
["baseball","Noun","Singular","","","","",""],
["foo","bar","baz","","","","",""]
];
const transformed = Object.assign(...data.map(([prop, value1, value2]) => ({ [prop]: [value1, value2] })));
console.log(transformed);

A bit simpler compared to other answers here but works as well.
const data = [
["baseball","Noun","Singular","","","","",""],
["baseball1","Noun1","Singular1","","","","",""],
["baseball2","Noun2","Singular2","","","","",""]
];
const obj = [];
data.forEach(function(i) {
let jsonObj = {};
jsonObj [i[0]] = i.slice(1).filter(x=>x !='');
obj.push(jsonObj)
});
console.log(JSON.stringify(obj))

Just using forEach, considering multiple array elements.
var obj = {};
var arr = [
["baseball", "Noun", "Singular", "", "", "", "", ""],
["Test", "Test1", "Test2", "", "", "", "", ""]
];
arr.forEach(function(val, idx) {
val.forEach(function(val1, idx1) {
if (idx1 === 0) {
obj[val1] = val.slice(1, val.length)
}
})
})
console.log(JSON.stringify(obj))

Related

How to convert object to objects Array

I need convert this object:
{
"en": "[\"En1\",\"En2\"]",
"de": "[\"De1\",\"De2\"]"
}
to:
[
{
"en": "En1",
"de": "De1"
},
{
"en": "En2",
"de": "De2"
}
]
Can you help me?
i tried as follows:
const obj = {
en: '["En1","En2"]',
de: '["De1","De2"]',
};
const result = Object.entries(obj).map(([key, value]) => ({
[key]: JSON.parse(value),
}));
console.log(result)
but this only returns me an array of objects and I don't know how to go ahead and create a new array with key-value matches.
const data = {
"en": "[\"En1\",\"En2\"]",
"de": "[\"De1\",\"De2\"]"
}
console.log(Object.values(Object.entries(data).reduce((a,[k,v])=>
(JSON.parse(v).forEach((e,i)=>(a[i]??={})[k]=e),a),{})))
You can separate your object into 2 arrays then combine them like this
const obj = {
en: '["En1","En2"]',
de: '["De1","De2"]',
};
// Convert to array, separate them by key
let en = JSON.parse(obj.en.split(','));
let de = JSON.parse(obj.de.split(','));
//then combine both arrays
const result = en.map((x,i) =>({
en:x,
de:de[i]
}))
console.log(result);
You can use a combination of Array#map and Array#reduce as follows. The number of items is not hard-corded, so this will work for any number of items:
const
input = { "en": "[\"En1\",\"En2\"]", "de": "[\"De1\",\"De2\"]"},
output = Object.entries(input)
.map(([key,vals]) => JSON.parse(vals).map(v => ({[key]:v})))
//..producing [[{"en":"En1"},{"en":"En2"}],.....]
.reduce(
(obj, values) =>
obj.length === 0 ?
values.map(v => v) : //initial result: [{"en":"En1"},{"en":"En2"}]
values.map((v,i) => ({...obj[i],...v})), //appends "de" prop to each element, ....
[]
);
console.log( output );
I've opted for a more imperative approach here. It appends objects to the returnArray array for each index of the parsed values array. If value matches idx + 1 (eg 'De1'.includes(1)), a key-value pair is initialized on the object at the current index of the returnArray array.
My answer relies on a lot of assumptions regarding the input. If the parsed string array elements are not in numerical order, or there are gaps in the values, eg De3, De1, De2, or De1, De6, the current solution doesn't account for it.
let returnArray = [];
Object.entries(obj).forEach(pair => {
let key = pair[0];
let values = JSON.parse(pair[1]);
values.forEach((_el, idx) => {
if (!returnArray[idx]) {
returnArray.push({});
}
let value = values[idx];
if (value.includes(idx + 1)) {
returnArray[idx][key] = values[idx];
}
});
});

pushing data inside an existing empty array

Basically I have an main object dataToMovie, I have empty arrays. I want to display the content of the arr variable into mov[] and the content of the arr2 into ser[]. I have attempted to do something as you can see. I am looking to do this seperately for each array as I will have multiple data in the future
const dataToMovie = {
createMovie,
links: {
mov: [],
ser: [],
rev: [],
ext: [],
},
};
const dataToInsert1 = {
'model-10389': 164703,
'model-10388': 164704,
'model-10387': 164705,
};
const dataToInsert2 = {
'model-10389': [1656, 1234, 1245],
'model-10384': [1656, 1234, 1245],
'model-10383': [1656, 1234, 1245],
};
const arr = Object.entries(dataToInsert1).map((entry) => ({
id: entry[0].substring(6, entry[0].length),
value: entry[1],
}));
//dataToMovie.links.mov[arr]
const arr2 = Object.entries(dataToInsert2).map(([key, value]) => ({
modelId: key.substring(6),
ids: value,
}));
//dataToMovie.links.ser[arr2]
concat is a good candidate for this operation. it returns a merged array.
dataToMovie.links.mov = dataToMovie.links.mov.concat( arr )
dataToMovie.links.ser = dataToMovie.links.set.concat( arr2 )
You are close. if the arrays are empty you can just do:
dataToMovie.links.mov = arr
dataToMovie.links.ser= arr2
If the arrays have items in them and you just want to add to them, you can use the spread operator
dataToMovie.links.mov = [...dataToMovie.links.mov, ...arr]
dataToMovie.links.ser = [...dataToMovie.links.ser, ...arr2]

Array of dictionaries to a single array of dictionary in javascript

I have a javascript array as
arr = [{"class":"a"},{"sub_class":"b"},{"category":"c"},{"sub_category":"d"}]
I want a new array as:
new_arr = [{"class":"a", "sub_class":"b", "category":"c", "sub_category":"d"}]
Is it possible to do this in Javascript without using a for loop to iterate through arr?
You can use Object.assign:
const array = [{
"class": "a"
}, {
"sub_class": "b"
}, {
"category": "c"
}, {
"sub_category": "d"
}]
const mergedObject = Object.assign({}, ...array);
// And put in an Array if that was intentional
const newArray = [mergedObject];
console.log(newArray);
I think that you want to merge objects. You could either use a spread operator or Object.assign. I don't see the point of having a single object inside an array. Considering your requirements you could do:
const merged = arr.reduce((list, curr) => {
return Object.assign({}, list, curr);
}, {});
const newArr = [merged];
You can try this.
var arr = [{"class":"a"},{"sub_class":"b"},{"category":"c"},{"sub_category":"d"}];
var res=[];
var res1=[];
res=Object.assign(...arr);
res1.push(res);
console.log("Result: ",res1);

How to rename JSON element in Nodejs

I have an API that response JSON data like this-
{
"unitcode":"apple",
"description":"bus",
"color":"red",
"intent":"Name 1"
}
I want to change like this-
{
"Value1":"apple",
"Value2":"bus",
"value3":"red",
"value4":"sale"
}
Presently, I can code to rename single key but i want some code to replace all key in one shot. my code like this-
request(baseurl)
.then( body => {
var unit = JSON.parse(body);
unit.intent = "sales"
unit.value1 = unit.unitcode
delete unit.unitcode;
console.log(unit)
console.log(unit.Value1)
var unit2 = JSON.stringify(unit)
// let code = unit.description;
conv.ask('Sales is 1 million metric tonnes ' + unit2);
})
please help me out on this and please little elaborate also to learn something new. thanks
Create a Map of original key to new key (transformMap). Convert the object to pairs of [key, value] with Object.entries(), iterate with Array.map() and replace the replacement key from the Map (or the original if not found). Convert back to an object with Object.toEntries():
const transformMap = new Map([
['unitcode', 'Value1'],
['description', 'Value2'],
['color', 'Value3'],
['intent', 'Value4']
]);
const transformKeys = obj =>
Object.fromEntries(
Object.entries(obj)
.map(([k, v]) => [transformMap.get(k) || k, v])
);
const obj = {
"unitcode": "apple",
"description": "bus",
"color": "red",
"intent": "Name 1"
};
const result = transformKeys(obj)
console.log(result)
If you know the object structure and it is constant, you could just use destructing like so.
const data = {
"unitcode":"apple",
"description":"bus",
"color":"red",
"intent":"Name 1"
};
// If the object is fixed and the fields are known.
const mapData = ({ unitcode, description, color, intent }) => ({
Value1: unitcode,
Value2: description,
Value3: color,
Value4: intent
});
console.log(JSON.stringify(mapData(data)));
But if the object has an unknown number of properties:
const data = {
"unitcode":"apple",
"description":"bus",
"color":"red",
"intent":"Name 1"
};
// If the object is fixed and the fields are known.
const mapData = (data) => {
return Object.keys(data).reduce((a,v,i) => {
a[`Value${i+1}`] = data[v];
return a;
}, {});
};
console.log(JSON.stringify(mapData(data)));
You can edit the array to have the values you need
let i=0,j=0,unit1={};
let unit = JSON.parse(body);
let unit3=["val1","val2","val3","val4"]
let unit5=Object.values(unit);
for(let key in unit){
unit1[unit3[i++]]=unit5[j++];
}
var unit2 = JSON.stringify(unit1)
console.log('Sales is 1 million metric tonnes \n' + unit2);
//Sales is 1 million metric tonnes
//{"val1":"apple","val2":"bus","val3":"red","val4":"Name 1"}
Well your target is to modify the keys and retain the value
In that context, you can iterate through your data. To dynamically generate keys as Value1, Value2, etc, we will append Value with iteration index which is going to be unique always.
const modifyInput = (input) => {
const modifiedInput = {}
Object.values(input).forEach((item, index) => {
modifiedInput[`Value${index + 1}`] = item
})
return modifiedInput
}
Use this function, pass your input and get your desired result

Two object arrays: merge with same key

I have two object arrays. I want to merge with key with value
var a = [{"fit":["34","32","30","28"],"size":["x"]}]
var b = [{"size":["s","m","xl"],"fit":["36"]}]
Expected Output should be
Obj=[{"fit":["34","32","30","28","36"],"size":["x,"s","m","xl"]}]
My Code is
let arr3 = [];
b.forEach((itm, i) => {
arr3.push(Object.assign({}, itm, a[i]));
});
alert(JSON.stringify(arr3))
it gives [{"size":["x"],"fit":["34","32","30","28"]}] which wrong.
Use Array.reduce().
// Combine into single array (spread operator makes this nice)
const myArray = [...a, ...b];
// "reduce" values in array down to a single object
const reducedArray = myArray.reduce((acc, val) => {
return [{fit: [...acc.fit, ...val.fit], size: [...acc.size, ...val.size]}];
});
Edit: if you want the reducer to merge objects regardless of what keys and fields it has then you can do by iterating over the keys of the objects and merging them dynamically:
const reducedArray = myArray.reduce((acc, val) => {
const returnObject = {};
for (const eaKey in acc) {
returnObject[eaKey] = [...acc[eaKey], ...val[eaKey]];
}
return [returnObject];
});
If the fields of the objects aren't guaranteed keys then you will need to get even more dynamic in detecting the type of merge and how to do it, but it's possible and I will leave that as an exercise for you to figure out. :)
Note that if there are duplicate values in each of the "fit" and "size" arrays, they will not be deduplicated. You'd have to do that manually as a separate step either with extra logic in the reduce function or afterwards.
combine a and b in a single array then reduce it starting with an array having an object with empty fit and size arrays:
var a = [{ fit: ["34", "32", "30", "28"], size: ["x"] }];
var b = [{ size: ["s", "m", "xl"], fit: ["36"] }];
var obj = [...a, ...b].reduce(
(acc, curr) => {
Object.keys(curr).forEach(k => {
acc[0][k] = [...new Set([...(acc[0][k] || []), ...curr[k]])];
});
return acc;
},
[{}]
);
console.log(obj);
You can create a combine function that takes fit and size from any two objects and merges them.
Use it as a reducer to combine everything.
let combine = ({fit, size}, {fit: fit2, size: size2}) =>
({ fit: [...fit, ...fit2], size: [...size, ...size2] });
let result = [...a, ...b].reduce(combine);
Example:
var a = [{"fit":["34","32","30","28"],"size":["x"]}, {"fit": ["10", "11"], "size":["xxxxxxxxl"]}]
var b = [{"size":["s","m","xl"],"fit":["36"]}];
let combine = ({fit, size}, {fit: fit2, size: size2}) =>
({ fit: [...fit, ...fit2], size: [...size, ...size2] });
let result = [...a, ...b].reduce(combine);
console.log(result);
If you don't want to use the keys directly you could try
const arr3 = b.reduce((carry, current, index) => {
Object.keys(current)
.forEach(key => {
Object.assign(carry, { [key]: Array.prototype.concat.call(current[key], a[index][key])});
});
return carry;
}, {});

Categories

Resources