I have a string in the form
Key=asdf, num=90, Key=ert, num=20, Key=yged, num=20, Key=kned, num=35
I have to filter only Key num pairs which has value 20 and store them into a Key Value pair such that Key=ert, num=20 will be first record and Key=yged, num=20 will be second record so on. How can I use Map in JavaScript so that always first value will go as key and second will go as value and form pairs in this case. I have used the following :
var dataString = JSON.parse(data).data;
var arrayVal = new Array();
arrayVal = dataString.split(', ');
for(a in arrayVal){
console.log(arrayVal[a]);
}
Array.map probably isn't the best tool for the job here. Array.reduce would be a better approach. Since you know what your delimiters are (namespaces and equal signs), you can logically split things up so that you know that every other iteration will give you a key/value. You can then create a mechanism to track what the last key is so you can map the value to it.
const str = 'Key=asdf, num=90, Key=ert, num=20, Key=yged, num=20, Key=kned, num=35';
const arr = str.split(', ').reduce( (acc, curr) => {
const entry = curr.split('=');
const key = entry[0];
const val = entry[1];
if (key === 'Key') {
acc['last_key'] = val
acc[val] = null;
} else if (key === 'num') {
acc[acc['last_key']] = val;
}
return acc;
}, {});
delete arr.last_key;
console.log(arr);
Here you go. It's kinda ugly.
let result = dataString.split(', ')
.map((value, index, array) =>
value === 'num=20' && array[index - 1])
.filter(x => x);
console.log(result);
Here's my say
const dataString = JSON.parse(data).data;
const arrayVal = dataString.split(', ');
const obj = {}; // initialize the object
for (let i = 0; i < arrayVal.length; i += 2) { // Iterating over two elements for the key and value
const key = arrayVal[i].split('=')[1];
const value = arrayVal[i + 1].split('=')[1];
obj[key] = value;
}
console.log(obj);
I have two arrays in an object named "customData". The arrays names are "headings" and "tabularData".
I want to modify "tabularData" array objects such that each object has properties matching first 6 properties of "headings" array and an "id" property in "tabularData".
sample "customData" object-
{
headings: [{"id":"k1"},{"id":"k2"},...,{"id":"k6"}],
tabularData: [{"k1":"v11","k2":"v12",...,"id":1},{"k1":"v21":"k2":"v22",...,"id":2}]
}
Expected result should be -
[{"k1":"v11","k2":"v12",...,"k6":"v16","id":1},
{"k1":"v21","k2":"v22",...,"k6":"v26","id":2}]
My code-
let selectedHeadings = customData.headings.slice(0, 6);
let array = [];
let temp = {};
customData.tabularData.forEach((eachObj) => {
for (const [key, value] of Object.entries(eachObj)) {
if (
selectedHeadings.find((heading) => heading.id === key) ||
key === "id"
) {
temp[key] = value;
array.push(temp);
}
}
});
console.log(array);
sanbox link
Please help.
To start with, it makes things much easier if you turn your selected headings into a map
let selectedHeadings = customData.headings.slice(0, 6).reduce((acc, h) => {
acc[h.id] = h;
return acc;
}, {});
Beyond that, you were pushing to the new array inside the inner loop, not the outer loop. You should also start a new temp object inside each outer loop. This should do it:
let array = [];
customData.tabularData.forEach((eachObj) => {
let temp = {};
for (const [key, value] of Object.entries(eachObj)) {
if (selectedHeadings[key] != undefined || key === "id") {
temp[key] = selectedHeadings[key] || value;
}
}
array.push(temp);
});
Forked Sandbox
Case: We have 'n' number of arrays stored in an array (Array of Arrays). Now that each child array in this parent array can have elements that may or may not be present in other child arrays. Output - I need to create an array which has the all the elements present in all the child arrays excluding the duplicates.
I do not want to concatenate all the arrays into a single array and use unique method to filter out. I need to create unique array then and there during iteration.
Ex:
var a[] = [1,2,3,4,5];
var b[] = [1,2,7,8];
var c[] = [1,2,3,4,5,6,7,8];
var d[] = [9,10,11,12];
var arr[] = [a,b,c,d]
Output must be [1,2,3,4,5,6,7,8,9,10,11,12]
P.S: I can concat the arrays and use jquery unique function to resolve this, but i need a solution in javascript alone. Thanks
You can use array#reduce to flatten your array and then use Set to get distinct values and use array#from to get back array from Set.
var a = [1,2,3,4,5];
var b = [1,2,7,8];
var c = [1,2,3,4,5,6,7,8];
var d = [9,10,11,12];
var arr = [a,b,c,d]
var result = Array.from(new Set(arr.reduce((r,a) => r.concat(a))));
console.log(result);
Try using .filter when adding each array to the final one, filtering out the duplicates:
a.filter(function(item) {
return !finalArray.contains(item));
});
Answer using Sets:
var a = [1,2,3,4,5];
var b = [1,2,7,8];
var c = [1,2,3,4,5,6,7,8];
var d = [9,10,11,12];
var concat = a.concat(b).concat(c).concat(d);
var union = new Set(concat);
//console.log(union);
ES6 Answer:
let a = new Set([1,2,3,4,5]);
let b = new Set([1,2,7,8]);
let c = new Set([1,2,3,4,5,6,7,8]);
let d = new Set([9,10,11,12]);
let arr = new Set([...a,...b,...c,...d]);
//Result in arr.
Whats going on???
From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set:
The Set object lets you store unique values of any type, whether
primitive values or object references.
So when we initialise Sets passing arrays to the constructor we basically ensure that there are no duplicate values.
Then in the last line, we concat all the Sets we initialised prior into a final set.
The ... notation converts the Set into an array, and when we pass the 4 arrays to the constructor of the Set they get concatenated and a Set of their unique values is created.
Here is a functional alternative written in ES5.
var flatten = function(list) {
return list.reduce(function(acc, next) {
return acc.concat(Array.isArray(next) ? flatten(next) : next);
}, []);
};
var unique = function(list) {
return list.filter(function(element, index) {
return list.indexOf(element) === index;
})
}
var a = [1,2,3,4,5];
var b = [1,2,7,8];
var c = [1,2,3,4,5,6,7,8];
var d = [9,10,11,12];
var arr = [a,b,c,d];
var result = unique(flatten(arr));
console.log(result);
If you support ES6, arrow function can make that code even shorter.
Here is a solution that uses a plain object for resolving duplicates, and only uses basic ES3 JavaScript. Runs in IE 5.5 and higher, and with O(n) time complexity.
function uniques(arr) {
var obj = {}, result = [];
for (var i = 0; i < arr.length; i++) {
obj[arr[i]] = true;
}
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) result.push(+prop);
}
return result;
}
// Example use
var a = [1,2,3,4,5],
b = [1,2,7,8],
c = [1,2,3,4,5,6,7,8],
d = [9,10,11,12];
var result = uniques(a.concat(b, c, d));
console.log('Result: ' + result);
As an object can only have a unique set of properties (no duplicates), the use of all array values as properties in an object will give you an object with a property for each unique value. This happens in the first loop. NB: the value given to those properties is not relevant; I have used true.
Then the result is just the conversion of those properties back to array values. This happens in the second loop.
var a = [1,2,3,4,5];
var b = [1,2,7,8];
var c = [1,2,3,4,5,6,7,8];
var d = [9,10,11,12];
var result = a.concat(b,c,d);
function remvDup(result){
var tmp = [];
for(var i = 0; i < result.length; i++){
if(tmp.indexOf(result[i]) == -1){
tmp.push(result[i]);
}
}
return tmp;
}
console.log(remvDup(result));
Becuase the OP mentioned that he cannot use 'Set' as it is not supported on the targeted browsers, I would recommand using the 'union' function from the lodash library.
See union's documentation here
My two arrays are:
const values = ['Master Clean', '45', '650']
const names = ['servicemenus.$.name', 'servicemenus.$.duration', 'servicemenus.$.cost']
The result should be like this:
{ 'servicemenus.$.name':'Master Clean', 'servicemenus.$.duration': '45', 'servicemenus.$.cost': 650}
Since I think that you know these two Arrays needs to be the same length at all time. This for loop could help you:
const values = ['Master Clean', '45', '650']
const names = ['servicemenus.$.name', 'servicemenus.$.duration', 'servicemenus.$.cost']
var obj = {}
for (var i = 0; i < names.length; i++) {
//or check with: if (values.length > i) { assignment }
obj[names[i]] = values[i];
}
console.log(obj);
Output will be this:
Object { servicemenus.$.name: "Master Clean", servicemenus.$.duration: "45", servicemenus.$.cost: "650" }
For completion, I found this Question could help you too: Merge two arrays into one Json object
You can work with the index of the array in a forEach to refer to the other and dynamically build the object keys:
const values = ['Master Clean', '45', '650']
const names = ['servicemenus.$.name', 'servicemenus.$.duration', 'servicemenus.$.cost']
let update = { };
names.forEach( (name,idx) => {
update[name] = values[idx];
});
And that gives you the result
From the assumption that the two arrays are always equal length, we can use one of them as the basis for a loop where we build the object:
let resultingObject = {};
names.forEach((name, i) => {
resultingObject[name] = values[i];
});
console.log(resultingObject);
You can reduce an array to a single value (object in your case). Reduce function accepts accumulator, current value and index which you can use to reference a value in the second array. Object.assign constructs an object with your keys/values.
const values = ['Master Clean', '45', '650'];
const names = ['servicemenus.$.name', 'servicemenus.$.duration', 'servicemenus.$.cost'];
const res = names.reduce((acc, cur, i) => Object.assign(acc, {[cur]: values[i]}), {});
console.log(res)
And with for in,loop through the object properties and assign it new object
var newobj = {};
for( var i in names){
newobj[names[i]] = values[i];
}
console.log(newobj);
So, I have this fuction that’s creating nested objects based on an array ok keys and I’m wondering how I could accomplish the same thing using lodash?
// nest
var nest = function (obj, keys, v) {
if (keys.length === 1) {
obj[keys[0]] = v;
} else {
var key = keys.shift();
obj[key] = nest(typeof obj[key] === 'undefined' ? {} : obj[key], keys, v);
}
return obj;
}
// sample data
var keys = ['user','name','fullName'];
var value = 'John Smith';
// create nested object
var obj = {};
obj = nest(obj, keys, value);
// log out new nested object
console.log(obj);
// include lodash somewhere...
// nest
var nest = function () {
return _.set(obj, path, value);
}
// sample data
// var keys = ['user','name','fullName']; can use a path now!
var path = 'user.name.fullName';
var value = 'John Smith';
// create nested object
var obj = {};
obj = nest(obj, path, value);
// log out new nested object
console.log(obj);