How to Map Array values from one Array to Another Array JavaScript? - javascript

This is my Code. Where I want to Pass the Values of kvArray to Second Array.
var kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
var reformattedArray = kvArray.map(obj => {
var payload = {};
payload["rt"];
payload["do"];
payload["f1"];
payload[obj.key] = obj.value;
console.log(payload["rt"]);
return payload;
});
The console.log is coming undefined.
Can anyone help here? I am pretty new to Map function.
I want to Print this result.
payload["do"]=10
payload["f1"]=20
payload["f2"]=30

var kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
var reformattedArray = kvArray.map(obj =>{
var payload = {};
const mapping = [null, 'rt', 'do', 'f1'];
const key = mapping[obj.key];
payload[key] = obj.value;
return payload;
});
console.log(reformattedArray);

You could use a destructuring assignment and build a new object with computed property names.
For the final keys, you could use an object keys with corresopnding keys to the the keys of the given object.
var kvArray = [{ key: 1, value: 10 }, { key: 2, value: 20 }, { key: 3, value: 30 }],
keys = { 1: 'rt', 2: 'do', 3: 'fi' },
result = kvArray.map(({ key, value }) => ({ [keys[key]]: value }));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

I'm not sure what format you want.
try the code below:
var kvArray = [{ key: 1, value: 10 },
{ key: 2, value: 20 },
{ key: 3, value: 30 }];
var reformattedArray = kvArray.map(obj => obj.value);
console.log(reformattedArray)
the result will be:
[ 10, 20, 30 ]

Not sure what you are trying to achieve with lines:
payload["rt"];
payload["do"];
payload["f1"];
If you want to create new keys in the reformatterArray, try assigning a value, eg.
var kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
var reformattedArray = kvArray.map(obj =>{
var payload = {};
payload["rt"] = "";
payload["do"]= "";
payload["f1"]= "";
payload[obj.key] = obj.value;
console.log(payload["rt"]);
return payload;
});
console.log(reformattedArray):
//result
0: {1: 10, rt: "", do: "", f1: ""}
1: {2: 20, rt: "", do: "", f1: ""}
2: {3: 30, rt: "", do: "", f1: ""}

You were assigning the value to payload but getting the values of payload.
var kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
var reformattedArray = kvArray.map(obj =>{
var payload = {};
payload[obj.key] = obj.value;
console.log(payload[obj.key]);
return payload;
});

You are mapping data to reformattedArray , so you need to pring reformattedArray to get values,
var kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
var reformattedArray = kvArray.map(obj =>{
var payload = {};
payload[obj.key] = obj.value;
return payload;
});
console.log(reformattedArray);
Also you have following code which is of no use
payload["rt"];
payload["do"];
payload["f1"];

This code works fine
let kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
let reformattedArray = kvArray.map(obj =>{
var payload = {};
payload[obj.key] = obj.value;
return payload;
});
console.log(reformattedArray)
The above code print output like this
[
0: {1: 10}
1: {2: 20}
2: {3: 30}
]
For more info, refer this link

Related

Array split into 2 and map the corresponding objects and put them in the resultant array

I have an array of array of objects similar to this:
arr = [{
val: 1,
ts: 123
}, {
val: 2,
ts: 125
}, {
val: 3,
ts: 120
}, {
val: 4,
ts: 113
}, {
val: 5,
ts: 117
}, {
val1: 6,
ts: 143
}, {
val1: 7,
ts: 193
}, {
val1: 8,
ts: 187
}, {
val1: 9,
ts: 115
}, {
val1: 10,
ts: 116
}]
The length of the array is always an even number. Now basically I'd like to split them in 2 halves
split1 = [{ val:1}, {val :2}, ......{val:5}]
split2 = [{val1:6},{val1:7},.......{val1:10}]
Now I have to map over these arrays and combine their fields(first item of array1 with first item of array2 and so on) into one single object and add an extra id to it such that result will look like
final = [{val:1, val1:6 , id:1} , {val:2, val1:7,id:3} , {val:3, val1:8,id:3},{val:4, val1:9,id:4},{val: 5, val1:10, id:5}]
This should hold for all arrays of even length and I want to make it a dynamic one. Keys will never be repeated inside source array
What I have tried is:
var res= a.splice(0, arr.length/2);
var c = a.map((val, ind) => { {val, res[ind]} })
Can someone guide here?
You can try this solution
const arr = [{ val: 1},{val: 2},{val: 3}, {val: 4} , {val:5},{ val1: 6},{val1: 7},{val1: 8}, {val1: 9} , {val1:10}]
const split = arr => [arr.slice(0, arr.length/2), arr.slice(arr.length/2, arr.length)]
const splitedArr = split(arr);
const merge = arr => {
const merged = []
for(let i = 0; i < arr[0].length; i++){
let newObj = {...arr[0][i], ...arr[1][i], id:(i+1)}
merged.push(newObj);
}
return merged;
}
const mergedArr = merge(splitedArr);
console.log(mergedArr);
You're quite close, some minor fixes
wrap map function implicit return with () instead of {}
for adding computed value you need to assign key name explicitly
need to destructure val or need to access val.val
const arr = [{ val: 1}, {val: 2}, {val: 3}, {val: 4}, {val: 5}, {val1: 6}, {val1: 7}, {val1: 8}, {val1: 9}, {val1: 10}];
const firstHalf = arr.slice(0, arr.length / 2);
const secondHalf = arr.slice(arr.length / 2);
const final = secondHalf.map((val, ind) => ({
...val,
...firstHalf[ind],
id: ind,
}))
console.log(final);
I have tried
var res= a.splice(0, arr.length/2);
var c = a.map((val, ind) => { {val, res[ind]} })
You're quite close. To make the map callback syntactically valid and create the desired object, it should be
var res = a.splice(0, arr.length/2);
var c = a.map((val, ind) => {
return {val: val.val, val1: res[ind].val1, id: ind+1};
})
or
var c = a.map((val, ind) => {
return Object.assign({id: ind+1}, val, res[ind]);
})

Reduce complexity O^2 of comparison between list of objects

I have two list of objects:
list1 = [{value: 'X'}, {value: 'Y'}, ..., {value: 'Z'}];
list2 = [{value: 'A'}, {value: 'B'}, ..., {value: 'C'}];
I have this code that checks whether the values in list2 are in list1. If it is the code doesn't do anything, if not it should add to list1 (this will create a new list, list3). Which means I'm doing a union between the two list without keeping the repeated values.
for (let i = list2.length-1; i >= 0; i--) {
let item = list2[i];
let shared = false;
for (let j = list1.length-1; j >=0; j--) {
let childItem = list1[j];
if (item.value === childItem.value) {
shared = true;
break;
}
}
if (!shared) { newValues.push(item); }
}
list3 = list1.concat(newValues);
This works fine, but I was wondering if I could improve this O(n*m).
I'm not sure if the lists are always sorted by default, but from what I've seen both (list1 and list2) are always sorted by value.
Example:
var list1 = [{value: 'bar'}, {value: 'baz'}, {value: 'foo'}, {value: 'foz'}];
var list2 = [{value: 'bar'}, {value: 'foo'}, {value: 'test'}, {value: 'testz'}];
var list3 = union(list1, list2);
list3 = [{value: 'bar'}, {value: 'baz'}, {value: 'foo'}, {value: 'foz'}, {value: 'test'}, {value: 'testz'}];
Create a set of the values of list1, and Filter list2 by the values in the set before concating it to list1:
var list1 = [{value: 'bar'}, {value: 'baz'}, {value: 'foo'}, {value: 'foz'}];
var list2 = [{value: 'bar'}, {value: 'foo'}, {value: 'test'}, {value: 'testz'}];
const union = (list1, list2) => list1.concat(
list2.filter(function({ value }) { // filter list2
return !this.has(value); // filter out items which value is in the set
}, new Set(list1.map(({ value }) => value))) // the set of list1 values
);
const list3 = union(list1, list2);
console.log(list3);
You could use a single loop and store the value in a set for later check. Complexity: O(n).
var list1 = [{ value: 'X' }, { value: 'Y' }, { value: 'C' }, { value: 'Z' }],
list2 = [{ value: 'A' }, { value: 'B' }, { value: 'C' }, { value: 'D' }],
list3 = list1
.concat(list2)
.filter((s => ({ value }) => !s.has(value) && s.add(value))(new Set));
console.log(list3);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Rapid way to find min and max values of a property in an array of objects

i have an array of objects like this:
arr = [
{name: "Alex", value: 1},
{name: "Bill", value: 2},
{name: "Jim", value: 3},
{name: "Dim", value: 5}
]
I want quick and clean way to have the min an max values of the value property
min = 1,
max = 5
You can use the reduce function on an array for min:
arr.reduce(function(prev, curr) {
return prev.value < curr.value ? prev : curr;
});
max would work in a similar way
Most performant would probably be a simple loop
arr = [
{name: "Alex", value: 1},
{name: "Bill", value: 2},
{name: "Jim", value: 3},
{name: "Dim", value: 5}
]
let min,max;
for (var i=arr.length; i--;) {
if ((!min) || arr[i].value < min) min = arr[i].value;
if ((!max) || arr[i].value > max) max = arr[i].value;
}
console.log(min, max)
Shortest to write, something like
arr = [
{name: "Alex", value: 1},
{name: "Bill", value: 2},
{name: "Jim", value: 3},
{name: "Dim", value: 5}
]
let m=Math,a=arr.map(z=>z.value);let [min,max]=[m.min(...a),m.max(...a)];
console.log(min,max)
var min = Number.POSITIVE_INFINITY,
max = Number.NEGATIVE_INFINITY;
arr.forEach(function(obj) {
min = Math.min(min, obj.value);
max = Math.max(max, obj.value);
});
You can use map() to return array of values and then use Math.max/min with spread syntax.
var arr = [{name:'Alex', value:1}, {name:'Bill', value:2},{name:'Jim', value: 3},{name: 'Dim', value:5}]
var values = arr.map(e => e.value);
var min = Math.min(...values);
var max = Math.max(...values);
console.log(max)
console.log(min)
You could either map the values and use Math function to get highest and the lowest value.
var arr = [{name:'Alex', value:1}, {name:'Bill', value:2},{name:'Jim', value: 3},{name: 'Dim', value:5}],
hash = arr.map(v => v.value),
min = Math.min.apply(Math, hash),
max = Math.max.apply(Math, hash);
console.log(min, max);
Or just sort the array of object based on the value property and choose the first and the last one.
var arr = [{name:'Alex', value:1}, {name:'Bill', value:2},{name:'Jim', value: 3},{name: 'Dim', value:5}],
hash = arr.sort((a,b) => a.value - b.value);
min = hash[0].value;
max = hash[hash.length-1].value;
console.log(min, max);
You can create a function to do it for you, and every time you need to find the min/max, it only takes you one line:
function findMM (arr) {
var minV;
var maxV;
var firstLoop = true;
arr.forEach(function(object){
if (firstLoop) {
minV = object.value;
maxV = object.value;
firstLoop = false;
} else {
if (object.value < minV){ minV = object.value }
if (object.value > maxV){ maxV = object.value }
}
});
return {min: minV, max: maxV};
}
//using the function
var results = findMM(arr);
console.log(JSON.stringify(results)); //output: {"min":1,"max":5}
Using reduce():
var arr = [{name:'Alex', value:1}, {name:'Bill', value:2},{name:'Jim', value: 3},{name: 'Dim', value:5}]
var result = arr.reduce(function(acc, val){
return { min: Math.min(acc.min, val.value),
max: Math.max(acc.max, val.value)}
}, {min: arr[0].value, max: arr[0].value});
console.log(result.max);
console.log(result.min);
You could sort your array using native Array.prototype.sort() and take the first and last value.
let data = [{
name: 'Ales',
value: 1
},
{
name: 'Dim',
value: 5
},
{
name: 'Bill',
value: 2
},
{
name: 'Jim',
value: 3
}
];
data = data.sort((a, b) => a.value - b.value);
let min = data [0].value;
let max = data [data .length - 1].value;
console.log('min:', min);
console.log('max:', max)
Notes:
If you use instead:
let min = data [0];
let max = data [data .length - 1];
you could return the full object which has a minimum or maximum value, which could be handy.

Create object from forEach

I'm trying to figure out if there's a way to rewrite this code as a single object creation:
my_array = [
{key: 1, value: "foo"},
{key: 2, value: "bar"}
];
let my_obj = {};
my_array.forEach((elem) => {
my_obj[elem.key] = elem.value;
});
What I'd like to do is something like:
my_array = [
{key: 1, value: "foo"},
{key: 2, value: "bar"},
];
const my_obj = ...?
Is there a way to do a one-shot conversion that's equivalent to the forEach call?
You can achieve this using Array.prototype.reduce():
var my_array = [{key: 1, value:"foo"}, {key: 2, value:"bar"}];
var my_object = my_array.reduce(function(prev, curr) {
prev[curr.key] = curr.value;
return prev;
}, {});
console.log(my_object); // {"1": "foo", "2": "bar"}
Alternatively, using ES6 syntax:
const my_object = my_array.reduce((prev, curr) => {
prev[curr.key] = curr.value;
return prev;
}, {});
In ES6, you can use Object.assign:
const obj = Object.assign({}, ...my_array.map(x => ({ [x.key]: x.value })));
// Or:
const obj = Object.assign({}, ...my_array.map(({ key, value }) => ({ [key]: value })));
This converts each { key: foo, value: bar } to { foo: bar }, then uses Object.assign to merge them into one object. (The spread operator is used as Object.assign expects a variable list of arguments.)
You can use the reduce function. It should work like this:
my_array = [
{key: 1, value: "foo"},
{key: 2, value: "bar"}
];
let my_obj = my_array.reduce(function(obj, elem) {
obj[elem.key] = elem.value;
return obj;
}, {});
// my_obj = { "1": "foo", "2": "bar" }

Merge duplicates in JavaScript Array

I have a stupid problem that at first seems to be simple to solve, but turns out to be tricky.
I have an array of objects, each with two properties: id and value:
[
{id: 2, value: 10},
{id: 4, value: 3},
{id: 2, value: 2},
{id: 1, value: 15}
]
I want to write an algorithm that sums up the values of ones with similar id.
My end result should be a new array with only the merged objects:
[
{id: 2, value: 12},
{id: 4, value: 3},
{id: 1, value: 15}
]
I've tried the following, but it doesn't work:
var arr = [];
arr.push({id: 2, visit:10});
arr.push({id: 4, visit:3});
arr.push({id: 2, visit:2});
arr.push({id: 1, visit:15});
// Deep copy
var copy = jQuery.extend(true, [], arr);
var masterArr = [];
for (var i = 0; i < arr.length; i++) {
var objArr = [];
objArr.push(arr[i]);
for (var j = copy.length-1; j > -1; j--) {
if (arr[i].id === copy[j].id) {
var q = copy.splice(j,1);
}
}
masterArr.push(objArr);
}
My plan was to first gather all similar objects in separate arrays (objArr), sum them up and put them in an end array (masterArr). I use jquerys extend to make a deep copy (not a reference) and reverse iteration and splice to remove objects thats already been found as "duplicates".
This doesn't work! And it doesn't seem to be a very efficient mehtod to solve my problem.
How could I do this? Performance isn't top priority but rather "nice to have"!
Thanks!
You can do it like this:
// Assuming:
a = [{id: 2, value: 10}, {id: 4, value: 3}, {id: 2, value: 2}, {id: 1, value: 15}]
var b = {}, // Temporary variable;
c = []; // This will contain the result;
// Build a id:value object ( {1: 15, 2: 12, 4: 3} )
a.map(function(current){b[current.id] = (b[current.id] || 0) + current.value});
for(var key in b){ // Form that into the desired output format.
c.push({id: parseInt(key, 10), value: b[key]});
}
console.log(c);
/* [{id: 1, value: 15},
{id: 2, value: 12},
{id: 4, value: 3}] */
I'm using parseInt(key, 10), since the keys are strings, you'll probably want them converted to integers again.
// First group the data based on id and sum the values
var temp = data.reduce(function(result, current) {
result[current.id] = (result[current.id] || 0) + current.value;
return result;
}, {});
// then recreate the objects with proper id and value properties
var result = [];
for (var key in temp) {
result.push({
id: parseInt(key, 10),
value: temp[key]
});
}
console.log(result);
Output
[ { id: 1, value: 15 },
{ id: 2, value: 12 },
{ id: 4, value: 3 } ]
The quickest approach loops over the array only once using Array.prototype.filter():
var tmp = {},
result = arr.filter(function (el) {
if (tmp.hasOwnProperty(el.id)) {
tmp[el.id].visit += el.visit;
return false;
}
else {
tmp[el.id] = el;
return true;
}
});
It also reuses the objects, though this renders the original array to contain inaccurate values. If this is a problem, you can modify the example to copy each object property to a new object.

Categories

Resources