Group array to an object in javascript - javascript

Hello apologies if this has been asked before but I can't search for the right term to find something useful.
Suppose if I had an array of
[
"0.001234", "2021-07-14 08:24:30"
"0.001245", "2021-07-14 01:04:24"
// etc etc ...
]
how would I change this to an object like so?
{
0: ["0.001234", "2021-07-14 08:24:30"]
1: ["0.001245", "2021-07-14 01:04:24"]
// etc etc ...
}

Edit - just noticed the format of your data - map reduce may not work for you, but still a similar principle:
let objForm = {}
for (let idx=0; idx<arrayForm.length; idx+=2) {
objForm[idx/2] = [ arrayForm[idx], arrayForm[idx+1] ]
}
Old answer:
You can use a reduce pattern.
let arrayForm = ["one", "two"]
let objForm = arrayForm.reduce((acc, val, idx) => ({
...acc,
[idx]: val
}), {})
console.log(objForm) // { 0: "one", 1: "two" }
The reduce method gets the accumulated value, the current value and the array index. In this case we are using the spread operator to add the next value to the object.
Note that the ( before the object definition is needed, so that JS doesn't confuse it with a code block.

Create a new object and then iterate over the array in element pairs and add them as a new array to the object.
const arr = [
'0.001234', '2021-07-14 08:24:30',
'0.001245', '2021-07-14 01:04:24'
];
const obj = {};
for (let i = 0; i < arr.length; i += 2) {
obj[i / 2] = [ arr[i], arr[i + 1] ];
}
console.log(obj);

Related

Javascript is empty after filling with data

Javascript array is empty after filling with values
I tried this code:
var browserdata = new Array();
// Fill the array with values
browserdata["qqq"] = "zzz";
browserdata["rrr"] = 1;
console.log(browserdata); // This shows an empty array
It should show { "qqq" => "zzz", "zzz" => 1 }
Actual output is [] (empty array).
You need to use Object data type instead of Array. Using object structure, you can assign properties to it and corresponding value for that property to get the desired output as { "qqq" => "zzz", "zzz" => 1 }
var browserdata = {};
// Fill the object with values
browserdata["qqq"] = "zzz";
browserdata["rrr"] = 1;
console.log(browserdata);
You can also use the another approach, to assign the property at the time object is declared:
var browserdata = {
'qqq': 'zzz',
'rrr': 1
};
console.log(browserdata);
It will never return empty as there are data in the array, with your code it will return an output
[qqq: "zzz", rrr: 1]
If you want to get an output like { "qqq" => "zzz", "zzz" => 1 } , You should use objects .Objects are nothing but a grouping of data,
for example, consider a student array with different data sets.
here you could define individual data or data sets like
student['name'] = john ;
student['mark'] = 20;
OR
students =[{name : john , mark :20} ,{name : rick, mark :20} ]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
https://javascript.info/array
If new Array() is called with a single argument which is a number, then it creates an array without items, but with the given length.
It’s rarely used, because square brackets [] are shorter. Also there’s a tricky feature with it lets see.
var arr = new Array(2); // will it create an array of [2] ?
console.log( arr[0] ); // undefined! no elements.
console.log( arr.length ); // length 2
var browserdata = new Array();
browserdata[0] = "zzz";
browserdata[1] = 1;
console.log(browserdata);
console.log(browserdata.length);
That solution works for me. Initializing with {} rather than [] or new Array() works. Thanks.
var browserdata = {};
// Fill the object with values
browserdata["qqq"] = "zzz";
browserdata["rrr"] = 1;
console.log(browserdata);
Only the positive integer keys of array object are displayed by default, but the rest of the properties can still be accessed and seen in the Google Chrome console.
var arr = []
arr[1] = 1
arr[-1] = -1
arr[.1] = .1
arr.a = 'a'
arr['b'] = 'b'
console.log( arr ) // [undefined, 1]
console.log( arr.b ) // "b"
console.log( { ...arr } ) // { "1": 1, "-1": -1, "0.1": 0.1, "a": "a", "b": "b" }

How to duplicate elements in a js array without creating "dependent elements"?

I am trying to modify a single element from an array whose elements were previously duplicated n times. To perform the array duplication I just relied on a custom function duplicateElements(array, times)from this post (see #Bamieh answer). As shown in the exemple below, the problem is I can't modify a single element from the array without modifying other elements:
function duplicateElements(array, times) {
return array.reduce((res, current) => {
return res.concat(Array(times).fill(current));
}, []);
}
var myvar = duplicateElements([{ a: 1 }, { a: 2 }], 2);
myvar[0].a = 3;
console.log(myvar);
// (4) [{…}, {…}, {…}, {…}]
// 0: {a: 3}
// 1: {a: 3}
// 2: {a: 2}
// 3: {a: 2}
// length: 4
As you can see myvar[1].a was also modified although this wasn't intended. How can I avoid this issue?
The problem is that you're passing the reference to the original object in Array(times).fill(current) .
In this case the two copies of the first {a:2} are the same copy of the original (They reference to the same space in memory) so if you change one, the two of them will change as they reference the same object in memory.
You have to make a deepcloning function or maybe spread the object inside a new one. You can change your original function to work with objects and primitives like this:
function duplicateElements(elementsArray, times) {
//Make a new placeholder array
var newArray = [];
//Loop the array of elements you want to duplicate
for (let index = 0; index < elementsArray.length; index++) {
//Current element of the array of element
var currentElement = elementsArray[index];
//Current type of the element to check if it is an object or not
var currentType = typeof currentElement
//Loop over the times you want to copy the element
for (let index = 0; index < times; index++) {
//If the new element is not an object
if (currentType !== "object" && currentType){
//append the element
newArray.push(currentElement)
//if it is an Object
} else if (currentType === "object" && currentType){
//append an spreaded new Object https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
newArray.push({...currentElement})
}
}
}
return newArray;
}
This is not the optimal way to do this, but I think that maybe you're new to javascript and is better to learn the old way of looping before using more Array functionalities (as the answer from Jonas Wilms, that is also a good answer).
I would recommend javascript.info and eloquent javascript to learn more about the language
The main reason for this as specified in the Array.fill documentation is that when dealing with objects it will copy by reference:
When fill gets passed an object, it will copy the reference and fill
the array with references to that object.
With lodash (and _.cloneDeep) that is one line like this:
let dubFn = (arr, t=1) =>
_.concat(arr, _.flatMap(_.times(t, 0), x => _.cloneDeep(arr)))
let r1 = dubFn([{a:1},{b:3}]) // no parameter would mean just 1 dub
let r2 = dubFn([{a:1},{b:3},5,[1]], 2) // 2 dublicates
r1[0].a = 3
r2[0].a = 3
console.log(r1)
console.log(r2)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Note that this now works with arrays/objects and primitives.
The idea is to use _.concat to return a new concatenated version of the input array with a combination of few functions which on the end return an array of cloned objects. We use _.times to return an array of in this case t elements and then for each of those elements we replace with a deep clone of the array. _.flatMap is needed to flatten the end result since we end up having array of arrays after the _.times call.
With ES6 you can do something like this:
let dubElements = (arr, t) =>
[...arr, ...new Array(t).fill().flatMap(x => arr.map(y => ({...y})))]
let r1 = dubElements([{a:1},{b:3}])
let r2 = dubElements([{a:1},{b:3}],2)
r1[0].a = 3
r2[0].a = 3
console.log(r1)
console.log(r2)
Where we concat arrays via the spread operator and we use new Array(t) to create the new duplicates array and make sure we fill it with undefined in this case after which we flatMap the results (which we map through the clone via the spread operator again.
Note that this works for your use case specifically. If you want to make it more generic you have to expand more in the last map function etc.
If you want to preserve the order of the elements you can do something like this:
let dubElements = (arr, t=1) => {
let _result = []
arr.forEach(x => {
for(let i=0; i<t+1; i++) {
_result.push({...x})
}
})
return _result
}
let result = dubElements([{a:1},{b:3}],2)
result[0].a = 3
console.log(result)
Replace
Array(times).fill(current)
which will add one reference to current multiple times to the array with:
Array.from({ length: times }, () => ({...current }))
which will shallow clone current. Note that the code will then only work with objects though, not with primitives.
I'd do:
const duplicateElements = (array, length) =>
array.flatMap(current => Array.from({ length }, () => ({ ...current }));

Why does changing the value of a property change the value for all similarly named properties in an array?

Why does changing the value of a property change the value for all similar properties in an array and how do I get it to work right without using the this keyword for 'name'?
let Object = {
'name' : 'Test Object'
}
let Array = []
Array.push(Object)
Array.push(Object)
Array.push(Object)
Array[0]['name'] = 'Changed'
console.log(Array) // expect only the first name to change, but all 3 change...
You aren't changing "similarly named" objects, you are changing the same object.
For non-primitives (basically everything that isn't a string, number, or boolean), they are passed by reference. That means when you add them to something like an array or pass them to a function, you are basically passing their address. If you pass it 3 times, they all point to the same address; there is still only one copy. Change one, and you change them all.
const a = { b: 1 };
const arr = [a, a, a];
// All the same object
console.log(arr[0] === arr[1], arr[1] === arr[2], a === arr[0]);
a.b = 5;
// All 3 changed, because it is the same thing
console.log(arr.map(a => a.b));
function someFunc(obj) { obj.b = 10 };
someFunc(a);
// changed from inside function, same object
console.log(a.b);
If you want to create a handful of objects that all start the same, but then are able to change afterwards, you need to create the objects in a loop:
const template = { name: 'a' };
const arr = [];
for (let i = 0; i < 3; i++) {
arr.push({ ...template }); // or: arr.push(Object.create({}, template))
}
arr[1].name = 'b';
arr[2].name = 'c';
console.log(arr);
Or, even more concisely:
// Creates a new Array with 3 records and then puts a copy of the template in each.
const template = { name: 'a' };
const arr = new Array(3).fill(1).map(() => ({ ...template }));
// or (without needing template variable):
// const arr = new Array(3).fill(1).map(() => ({ name: 'a' }))
arr[1].name = 'b';
arr[2].name = 'c';
console.log(arr);
When you invoke Array.push(Object), you're pushing a reference to the same object into the array 3 times. Push does not make a copy of Object - only 1 Object exists.
If you want 3 identical objects in an array, try something like this:
let vArray = []
for(i = 0; i <= 2; i++) {
//We're going to loop this 3 times, creating 3 different
//objects and pushing each of them into the array
let vObject = {
'name' : 'Test Object'
}
vArray.push(vObject)
}
vArray[0]['name'] = 'Changed'
console.log(vArray) // Only the first one will have been changed.
The answer I was looking for was to change the syntax in my answer to Array.push({...Object}). This creates a 'new' object to be pushed, with only 5 additional characters...
I didn't know 'object spread syntax' essentially did this.

storing key value pairs in an array in javascript

I have 2 arrays namely,
configdata = ["assignee", "shortDesc"];
ticketarray = ["Tom","testDesc"];
I want to store the values as a key value pair in another array, something like this:
ticketData = ["assignee":"Tom","shortDesc":"testDesc"];
Kindly note that the array values are dynamic, so I cannot hardcode them.
Is there a way to do so? I am able to achieve the above said requirement but the length always shows 0. This is the code that I am using:
configdata.Incident_Field.forEach(function (k, i) {
this[k] = ticketarray[i];
}, ticketData);
Other people have explained why your code did not work. I am providing another solution using reduce.
const configdata = ["assignee", "shortDesc"];
const ticketarray = ["Tom", "testDesc"];
let ticketData = configdata.reduce((result, value, index) => {
result[value] = ticketarray[index];
return result;
}, {});
console.log(ticketData);
Output:
{
assignee: "Tom",
shortDesc: "testDesc"
}
The below is not a valid structure in JavaScript:
ticketData = ["assignee":"Tom","shortDesc":"testDesc"];
What you need is a JavaScript object. The best you can do is:
Make sure both the array lengths are same.
Associate the key and value by creating a new object.
Use Object.keys(obj).length to determine the length.
Start with the following code:
configdata = ["assignee", "shortDesc"];
ticketarray = ["Tom", "testDesc"];
if (configdata.length == ticketarray.length) {
var obj = {};
for (var i = 0; i < configdata.length; i++)
obj[configdata[i]] = ticketarray[i];
}
console.log("Final Object");
console.log(obj);
console.log("Object's Length: " + Object.keys(obj).length);
The above will give you an object of what you liked, a single variable with all the values:
{
"assignee": "Tom",
"shortDesc": "testDesc"
}

How can I push an object into an array?

I know it's simple, but I don't get it.
I have this code:
// My object
const nieto = {
label: "Title",
value: "Ramones"
}
let nietos = [];
nietos.push(nieto.label);
nietos.push(nieto.value);
If I do this I'll get a simple array:
["Title", "Ramones"]
I need to create the following:
[{"01":"Title", "02": "Ramones"}]
How can I use push() to add the object into the nietos array?
You have to create an object. Assign the values to the object. Then push it into the array:
var nietos = [];
var obj = {};
obj["01"] = nieto.label;
obj["02"] = nieto.value;
nietos.push(obj);
Create an array of object like this:
var nietos = [];
nietos.push({"01": nieto.label, "02": nieto.value});
return nietos;
First you create the object inside of the push method and then return the newly created array.
can be done like this too.
// our object array
let data_array = [];
// our object
let my_object = {};
// load data into object
my_object.name = "stack";
my_object.age = 20;
my_object.hair_color = "red";
my_object.eye_color = "green";
// push the object to Array
data_array.push(my_object);
Using destructuring assignment (ES6)
const nieto = {label: 'title', value: 'ramones' }
const modifiedObj = {01: nieto.label, 02: nieto.value}
let array = [
{03: 'asd', 04: 'asd'},
{05: 'asd', 06: 'asd'}
]
// push the modified object to the first index of the array
array = [modifiedObj, ...array]
console.log(array)
If you'd like to push the modified object to the last index of the array just change the destructured array ...array to the front.
array = [...array, modifiedObj]
Well, ["Title", "Ramones"] is an array of strings. But [{"01":"Title", "02", "Ramones"}] is an array of object.
If you are willing to push properties or value into one object, you need to access that object and then push data into that.
Example:
nietos[indexNumber].yourProperty=yourValue; in real application:
nietos[0].02 = "Ramones";
If your array of object is already empty, make sure it has at least one object, or that object in which you are going to push data to.
Let's say, our array is myArray[], so this is now empty array, the JS engine does not know what type of data does it have, not string, not object, not number nothing. So, we are going to push an object (maybe empty object) into that array. myArray.push({}), or myArray.push({""}).
This will push an empty object into myArray which will have an index number 0, so your exact object is now myArray[0]
Then push property and value into that like this:
myArray[0].property = value;
//in your case:
myArray[0]["01"] = "value";
I'm not really sure, but you can try some like this:
var pack = function( arr ) {
var length = arr.length,
result = {},
i;
for ( i = 0; i < length; i++ ) {
result[ ( i < 10 ? '0' : '' ) + ( i + 1 ) ] = arr[ i ];
}
return result;
};
pack( [ 'one', 'two', 'three' ] ); //{01: "one", 02: "two", 03: "three"}
The below solution is more straight-forward. All you have to do is define one simple function that can "CREATE" the object from the two given items. Then simply apply this function to TWO arrays having elements for which you want to create object and save in resultArray.
var arr1 = ['01','02','03'];
var arr2 = ['item-1','item-2','item-3'];
resultArray = [];
for (var j=0; j<arr1.length; j++) {
resultArray[j] = new makeArray(arr1[j], arr2[j]);
}
function makeArray(first,second) {
this.first = first;
this.second = second;
}
This solution can be used when you have more than 2 properties in any object.
const nieto = {
label: "Title",
value: "Ramones"
}
let nietos = [];
let xyz = Object.entries(nieto)
xyz.forEach((i,j)=>{
i[0] = `${(j+1).toLocaleString("en-US", {
minimumIntegerDigits: 2,
useGrouping: false,
})}`
})
nietos.push(Object.fromEntries(xyz))

Categories

Resources