Javascript array built dynamically in a loop - javascript

I have an array, say
var arr = ["id", "currency", "region", "status"]
How can I map the above to an object literal, as below?
var columns = [
{ key:"id", headerRenderer:"id" },
{ key:"currency", headerRenderer:"currency" },
{ key:"status", headerRenderer:"region" },
{ key:"region", headerRenderer:"status" }
];
Thanks in advance!

One solution is to use Array#map method.
The map() method creates a new array with the results of calling a provided function on every element in this array.The provided function is a callback.
So, as I said above map method provided callback function once for each element in an array, in order, and constructs a new array from the results. The elements from the result array are objects, like this: {"key":item, "headerRenderer":item}.
var array = ["id", "currency", "region", "status"]
var columns=array.map(function(item){
return {
"key":item,
"headerRenderer":item
}
});
console.log(columns);

The map method on the Array prototype allows you to apply a function to every element in an array, thereby effectively abstracting iteration for simple cases. Your case is simple, because the content of any entry in result is completely specified by its corresponding entry in arr, which means you can "map"
"id" --> { key: "id", headerRenderer: "id" }
Using map you can solve your problem in just one line (provided your environment supports ES6):
var arr = ["id", "currency", "region", "status"]
var result = arr.map(key => ({ key, headerRenderer: key }));
console.log(result);

var columns = [];
var array = ["id", "currency", "region", "status"];
for (var i = 0, len = array.length; i < len; i++) {
columns.push({
key: array[i],
headerRenderer: array[i]
});
}

Normally .map() is the way but another functional approach would be to use a tail call recursive map as follows;
var arr = ["id", "currency", "region", "status"],
mapo = (a, r=[]) => a.length ? mapo(a.slice(1),r.concat({key:a[0],headerRenderer:a[0]})) : r;
console.log(mapo(arr));

Related

Array of objects: accessing an object's value without iterating through the array

I have an array of similarly structured objects:
var my_arr = [{property1: some_value, property2: another_value}, {}, {}, ...];
Currently, to find the object containing a target value, I iterate through each element of the array:
var my_obj, target_value;
for (let obj_in_arr of my_arr) {
if (obj_in_arr.property1 === target_value) {
my_obj = obj_in_arr;
break;
}
}
Is there a faster way? How can I access the object with the target value directly, without resorting to iteration?
If you prepopulate a new Map all subsequent searches will be in O(1)
const objMap = new Map()
for (let obj of my_arr) {
objMap.set(obj.property1, obj)
}
function getObject(target, map) {
return map.get(target)
}
I think you need to iterate the array anyway, but you can try _.findIndex of underscore.js
http://underscorejs.org/#findIndex
If you only need to find a value once, then iteration is really the only way.
If you will want to find many values in the array, you could create an object keyed on your target property to serve as a lookup table:
var lookup = {};
for (var i = 0; i < my_arr.length; i++) {
lookup[my_arr[i].property1] = my_arr[i];
}
That front loads some work, but could save you time ultimately if you have many lookups to make.
Lookups would be as simple as:
my_obj = lookup[target_value];
If you have access to es2015 you could make your lookup table generation a little more concise:
const lookup = my_arr.reduce((m, v) => (m[v.property1] = v, m), {});
this will still iterate through the array but you could use the native js find function.
const objArray = [{ val: 1}, { val: 2}];
const targetObj = objArray.find((obj) => obj.val == 2 ) // { val: 2}

Convert array of strings into an array of objects

I have this JavaScript array:
[ "124857202", "500255104", "78573M104" ]
I want to convert this particular array into an array of objects as shown below:
[
{ name: "124857202" },
{ name: "500255104" },
{ name: "78573M104" }
]
Use Array#map to convert each value into a different value:
var newArr = arr.map(function(value) {
return {name: value};
});
Array#map applies the callback to each element in the array and returns a new array containing the return values of the callback.
I would take a look at the array.map function in javascript.
const mappedArr = arr.map(value => {
return {
name: value
}
})
I want to convert this particular array into an array of objects as
shown below
If you want to change the actual array in place (rather than creating a new array), you can use a for loop to iterate the indexes of your array. For each index, you can replace the value with an object {name: arr[i]}. This object has a name key, and takes a value which is the current element arr[i].
const arr = [ "124857202", "500255104", "78573M104" ];
for(let i = 0; i < arr.length; i++) {
arr[i] = {name: arr[i]};
}
console.log(arr);
Or, if you want to make a new array and leave the original untouched, you can use Felix's answer, here it can be re-written to use more modern ES6 features to make it more concise, such as an arrow function and shorthand property names:
const arr = [ "124857202", "500255104", "78573M104" ];
const res = arr.map(name => ({name}));
console.log(res);
Another approach - Array#reduce.
var arr = ["124857202", "500255104", "78573M104"];
var res = arr.reduce(function(s, a){
s.push({name: a});
return s;
}, [])
console.log(res);
You can use
var arrayOfStrings = ["124857202", "500255104", "78573M104"];
var arrayOfObjects = [];
arrayOfStrings.forEach(function (element, index) {
arrayOfObjects.push({
name: element,
})
});
Felix Kling' answer, gehsekky's answer and the second part of Nick Parsons' answer are the most correct. For completeness, here is a version that uses Underscore's _.map:
import { map } from 'underscore';
var result = map(array, name => ({name}));
For this particular use case, _.map doesn't buy you much compared to Array.prototype.map except for a little bit of added portability. Going the other way, however, is a bit easier on the brain with _.map because of Underscore's iteratee shorthands:
// Underscore map
var array = map(result, 'name');
// Array.prototype.map
var array = result.map(obj => obj.name);
Underscore's map and other collection functions really shine when you need to iterate over a plain object, since JavaScript's built-in methods don't support this at all:
var objectOfStrings = {
first: "124857202",
second: "500255104",
third: "78573M104"
};
// to array of strings, Underscore
var arrayOfStrings = map(objectOfStrings);
// to array of strings, vanilla JS
var arrayOfStrings = [], value;
for (key in objectOfStrings) {
arrayOfStrings.push(objectOfStrings[key]);
}
// to array of objects, Underscore
var arrayOfObjects = map(objectOfStrings, name => ({name}));
// to array of objects, vanilla JS
var arrayOfStrings = [], name;
for (key in objectOfStrings) {
name = objectOfStrings[key];
arrayOfStrings.push({name});
}
var objectOfObjects = {
first: {name: "124857202"},
second: {name: "500255104"},
third: {name: "78573M104"}
};
// to array of strings, Underscore
var arrayOfStrings = map(objectOfStrings, 'name');
// to array of strings, vanilla JS
var arrayOfStrings = [], value;
for (key in objectOfObjects) {
arrayOfStrings.push(objectOfObjects[key].name);
}
// to array of objects, Underscore
var arrayOfObjects = map(objectOfObjects);
// to array of objects, vanilla JS
var arrayOfObjects = [], value;
for (key in objectOfStrings) {
arrayOfObjects.push(objectOfStrings[key]);
}

Reduce JSON with JS

I am trying to reduce a JSON array. Inside the array are other object, I am trying to turn the attributes into their own array.
Reduce Function:
// parsed.freight.items is path
var resultsReduce = parsed.freight.items.reduce(function(prevVal, currVal){
return prevVal += currVal.item
},[])
console.log(resultsReduce);
// two items from the array
// 7205 00000
console.log(Array.isArray(resultsReduce));
// false
The reduce function is kind of working. It gets both item from the items array. However I am having a couple problems.
1) The reduce is not passing back an array. See isArray test
2) I am trying to make a function so I can loop through all of the attributes in the array the qty, units, weight, paint_eligable. I cannot pass a variable to the currVal.variable here
Attempting:
var itemAttribute = 'item';
var resultsReduce = parsed.freight.items.reduce(function(prevVal, currVal){
// pass param here so I can loop through
// what I actually want to do it create a function and
// loop through array of attributes
return prevVal += currVal.itemAttribute
},[])
JSON:
var request = {
"operation":"rate_request",
"assembled":true,
"terms":true,
"subtotal":15000.00,
"shipping_total":300.00,
"taxtotal":20.00,
"allocated_credit":20,
"accessorials":
{
"lift_gate_required":true,
"residential_delivery":true,
"custbodylimited_access":false
},
"freight":
{
"items":
// array to reduce
[{
"item":"7205",
"qty":10,
"units":10,
"weight":"19.0000",
"paint_eligible":false
},
{ "item":"1111",
"qty":10,
"units":10,
"weight":"19.0000",
"paint_eligible":false
}],
"total_items_count":10,
"total_weight":190.0},
"from_data":
{
"city":"Raleigh",
"country":"US",
"zip":"27604"},
"to_data":
{
"city":"Chicago",
"country":"US",
"zip":"60605"
}
}
Thanks in advance
You may need Array#map for getting an array of items
var resultsReduce = parsed.freight.items.reduce(function (array, object) {
return array.concat(object.item);
}, []);
The same with a given key, with bracket notation as property accessor
object.property
object["property"]
var key = 'item',
resultsReduce = parsed.freight.items.reduce(function (array, object) {
return array.concat(object[key]);
}, []);

JS: Convert a specific values from an object into an array?

I have an object:
var obj =
[
{
"value": "aep",
"label": "AEP"
},
{
"value": "cap",
"label": "CAP"
},
{
"value": "casl",
"label": "CASL"
} ]
And I want to convert the values of the labels ONLY into an array so that the end result is:
["AEP", "CAP", "CASL"]
How do I only get the label values converted in an array?
First: obj is not an object, it is an array since the parent brackets are [] and not {}. I will, however, keep the name the same. This might have caused you some confusion, e.g.
var object = {};
var array = [];
var arrayOfObjects = [{},{},{}];
var objectOfArrays = {array1: [],array2: [],array3: []};
To loop an array you can use a for loop:
// new array
var newArray = [];
// iterates over each index in the array
for(var i=0; i<obj.length; i++) {
// Access the specific index, then access its `label` property
// Push into `newArray`
newArray.push(obj[i].label);
}
console.log(newArray);
Codepen: http://codepen.io/theblindprophet/pen/RRxVba
Using a for loop
var out = [];
for (var i = 0, len = obj.length; i < len; i++) {
out.push(obj[i].label);
}
console.log(out);
Its simple. You can use map function of javascript array
var obj =
[
{
"value": "aep",
"label": "AEP"
},
{
"value": "cap",
"label": "CAP"
},
{
"value": "casl",
"label": "CASL"
} ]
var arr = obj.map(function(data){return data.value});
This is a functional solution and not the most straightforward one, you may want to refer to #theblindprophet's answer for the imperative approach to this problem.
Pretty easy task to be done in a functional way:
var labels = obj.map(function(inner) { return inner.label });
How does one approach such a problem: You need to think of how to transform the data you have to the data you want. In this case you have an Array of Objects and you want to transform this Array of Objects to an Array of Strings placed inside that Object.
The above code iterates over the Array and returns the value you want for the current element of the Array, building a new Array in the course (map)

How to get unique objects from objects array in javascript

I have an array of objects that looks like the image below. Is there a way by which I can have an array that contains unique objects with respect to id ? We can see below that the id are same at index [0] and index [2].
Is there a way that I can get an array containing objects with unique id and the first object from the last index is added to the unique array rather than the first object. In this case, Object at index[2] should be added instead of object at index[0]:
To get an array of "unique" objects(with last index within the list) for your particular case use the following approach (Array.forEach, Array.map and Object.keys functions):
// exemplary array of objects (id 'WAew111' occurs twice)
var arr = [{id: 'WAew111', text: "first"}, {id: 'WAew222', text: "b"}, {id: 'WAew111', text: "last"}, {id: 'WAew33', text: "c"}],
obj = {}, new_arr = [];
// in the end the last unique object will be considered
arr.forEach(function(v){
obj[v['id']] = v;
});
new_arr = Object.keys(obj).map(function(id) { return obj[id]; });
console.log(JSON.stringify(new_arr, 0, 4));
The output:
[
{
"id": "WAew111",
"text": "last"
},
{
"id": "WAew222",
"text": "b"
},
{
"id": "WAew33",
"text": "c"
}
]
The best way to do this is to modify your data structure into an object itself where each key is one of the IDs:
{
"WadWA7WA6WAaWAdWA...": {
"text": "birla"
},
"WadWA...": {
"test": "ab"
}
}
and so forth. If the data comes from a source formatted that way, you can always map the array of results to this format.
You could create a hash using the id as the key and keeping the value as the entire object:
var myHash = new Object();
var i;
for(i = 0; i < yourArray.length; i++) {
var yourObjId = yourArray[i][id];
myHash[yourObjId] = yourArray[i];
}
You would be left with a hash myHash containing objects with unique id's (and only the last object of duplicates would be stored)
Try this: just add to a new object using id as the key
var arr = [{id:'123', text: 'a'}, {id:'234', text: 'b'}, {id:'123', text: 'c'}];
var map = new Object();
for(var i in arr){ map[arr[i].id] = arr[i]; }
var newArr = [];
for(var i in map){ newArr.push(map[i]); }
newArr shall contain the 2nd and 3rd object.

Categories