Related
["10","13"] is the array, need to find the values between them and flatten the array with the values -> ["10","11","12","13"].
The first array above (["10", "13"]) is in a list of arrays.
const OriginalData = {
Red:{
Name:"L",
List:[
["1", "5"],
["2", "5"],
["7", "9" ],
]
},
Blue:{
Name:"BL",
List:[
["1", "5"],
["7", "9" ],
["10", "13" ],
["15", "20"]
]
},
Black:{
List:[
["Random"],
"Random2"
]
}
}
Then finally Object must look like,
{
Level:{
Name:"L",
List:[
1, 2, 3, 4, 5, 7, 8, 9
]
},
Basement:{
Name:"BL",
List:[
1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20
]
},
Custom:{
List:[
"Random",
"Random2"
]
}
}
What It should do:
Take the first object, inside List there are set of ranges, the values between those ranges should be found a flatten without duplicates.
Finding the values between is only for "Red", and "Blue", In "Black" key only flatten is needed.
I tried,
Code:
const submitData = () => {
let obj = originalData;
let flattenedArray = [].concat.apply([], originalData.Red.List);
let uniqueArray = flattenedArray.filter(
(v, i, a) => a.indexOf(v) === i
);
obj = {
...originalData,
Red: {
...originalData.Red,
List: uniqueArray,
},
};
console.log(obj);
};
The above code flattens the array but will not find between the numbers and it only worked for key "Red"
A simple example to create a range:
let example = ["10","13"];
let min = Math.min(...example);
let max = Math.max(...example);
let result = [];
for (i = min; i <= max; i++) {
result.push(i);
}
console.log(min, max, result)
You can easily achieve it with a simple logic and will work for random numbers as well.
Try this (Descriptive comments of implementation has been added in the below code snippet) :
const OriginalData = {
Red:{
Name:"L",
List:[
["1", "5"],
["2", "5"],
["7", "9" ],
]
},
Blue:{
Name:"BL",
List:[
["1", "5"],
["7", "9" ],
["10", "13" ],
["15", "20"]
]
}
};
Object.keys(OriginalData).forEach(key => {
// Flatten the original array list.
OriginalData[key].List = OriginalData[key].List.flat()
// Find min and max numbers from the array.
const min = Math.min(...OriginalData[key].List);
const max = Math.max(...OriginalData[key].List);
// empty existing list array.
OriginalData[key].List = [];
// Now using for loop assign the values to the list array based on min and max value.
for (let i = min; i <= max; i++) {
OriginalData[key].List.push(i);
}
});
// Result
console.log(OriginalData);
To create an array of all the numbers in a given range, you can create a new array with the required size and then map each of it's entries to the entry's index plus the given lower bound.
function fillRange(r) {
let b = +r[1]
let a = +r[0]
if (a > b) {
let tmp = a
a = b
b = tmp
}
return Array(b - a + 1).fill(0).map((e, i) => a + i)
}
This function flattens an array and removes all duplicate entries.
function union(arrays) {
let flattened = [].concat.apply([], arrays)
return flattened.reduce(
(total, e) => {
let i = total.indexOf(e)
if (i === -1) {
total.push(e)
}
return total
}, [])
}
Then this code produces the desired result from a list of ranges:
function unionRanges(ranges) {
let expanded = ranges.map((e) => fillRange(e))
return union(expanded).sort((a,b) => (a-b))
}
The final object can be created like this:
function processData(data) {
let res = {}
res.Level = {}
res.Basement = {}
res.Custom = {}
res.Level.Name = data.Red.Name;
res.Level.List = unionRanges(data.Red.List)
res.Basement.Name = data.Blue.Name
res.Basement.List = unionRanges(data.Blue.List)
res.Custom.List = union(data.Black.List)
return res
}
You can flat the array, get the min and max and finally with a loop create the desired array.
const array = [["1","5"],["7","9"],["10","13"],["15","20"]];
const flatted = array.flat();
const min = Math.min(...flatted);
const max = Math.max(...flatted);
const result = Array.from({length: max + 1 - min}).map(function(_, i) {
return i + min;
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Hope the below codes help you.
const OriginalData = {
Red: {
Name: "L",
List: [
["1", "5"],
["2", "5"],
["7", "9"],
]
},
Blue: {
Name: "BL",
List: [
["1", "5"],
["7", "9"],
["10", "13"],
["15", "20"]
]
},
Black: {
List: [
["Random"],
"Random2"
]
}
};
//Iterating over the object OriginalData
Object.keys(OriginalData).forEach(key => {
// Flatten the array "List" of each element
OriginalData[key].List = OriginalData[key].List.flat();
// Checking if the flatten array contains integers
if (!isNaN(parseInt(OriginalData[key].List[0]))) {
// Calculating the min and max of the "List" array
const min = Math.min(...OriginalData[key].List);
const max = Math.max(...OriginalData[key].List);
let tmpArr = [];
// Generating the array with numbers from min to max
for (let i = min; i <= max; i++) {
tmpArr.push(i);
}
// Updating the original "List" (containing integers) of each element
OriginalData[key].List = tmpArr;
}
});
console.log(OriginalData);
Imagine I have this array of arrays:
myData = [
["wantThisAsKey1",someElement1,anotherElement1],
["wantThisAsKey2",someElement2,anotherElement2]
]
I need to convert this array to an object where the first element of each array is used as the key:
myDataObject = {
"wantThisAsKey1": [someElement1,anotherElement1],
"wantThisAsKey2": [someElement2,anotherElement2],
}
How can I do this in a general way, something like myDataObject = convertToObject(myData) ?
Try this:
let myData = [
["wantThisAsKey1","someElement1","anotherElement1"],
["wantThisAsKey2","someElement2","anotherElement2"]
];
let myDataObject = convertToObject(myData);
console.log(myDataObject);
function convertToObject(data){
let res = {};
for(let i = 0; i < data.length; i++)
res[data[i][0]] = data[i].slice(1);
return res;
}
To achieve this you can combine the arrays reduce function with destructuring assignment:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
myData = [
["wantThisAsKey1", 1, 2],
["wantThisAsKey2", 2, 3]
]
const newobject = myData.reduce((acc, elem) => {
const [key, ...rest] = elem;
acc[key] = rest
return acc;
}, {})
console.log(newobject);
// Result: { wantThisAsKey1: [ 1, 2 ], wantThisAsKey2: [ 2, 3 ] }
try using reduce here. like this.
const result = myData.reduce( (result, ele) => {
const [key, ...other] = ele
result[key] = other
return result
}, {})
// output = { wantThisAsKey1: [ 'someElement1', 'anotherElement1' ], wantThisAsKey2: [ 'someElement2', 'anotherElement2' ] }
I have 2 array, one for key and other for value.
Want create new array with these arrays.
key: [01, 02, 03]
value: ["hi", "hello", "welcome"]
Output I need:
[
{"key": "1","value":"hi"},
{"key": "2","value":"hello"},
{"key": "3","value":"welcome"}
]
How to get result by this way.?
My code:
output = key.map(function(obj, index){
var myObj = {};
myObj[value[index]] = obj;
return myObj;
})
Result:
[
{"1","hi"},
{"2","hello"},
{"3","welcome"}
]
const keys = [01, 02, 03];
const values = ['hi', 'hello', 'welcome'];
const res = keys.map((key, ind) => ({ 'key': ''+key, 'value': values[ind]}));
console.log(res);
There is also a proposal for the following method of Object, fromEntries, which will do exactly what you want to, but it is not supported yet by the major browsers:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries
var myArray = [];
var keys = [45, 4, 9];
var cars = ["Saab", "Volvo", "BMW"];
cars.forEach(myFunction);
var txt=JSON.stringify(myArray);
document.getElementById("demo").innerHTML = txt;
function myFunction(value,index,array) {
var obj={ key : keys[index], value : value };
myArray.push(obj);
}
<p id="demo"></p>
You could take an object with arbitrary count of properties amd map new objects.
var key = [1, 2, 3],
value = ["hi", "hello", "welcome"],
result = Object
.entries({ key, value })
.reduce((r, [k, values]) => values.map((v, i) => Object.assign(
{},
r[i],
{ [k]: v }
)), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Here you have another apporach using reduce():
let keys = [01, 02, 03];
let values = ['hi', 'hello', 'welcome'];
let newArray = keys.reduce((res, curr, idx) => {
res.push({'key': curr.toString(), 'value': values[idx]});
return res;
}, []);
console.log(newArray);
how to count the value of object in new object values
lets say that i have json like this :
let data = [{
no: 3,
name: 'drink'
},
{
no: 90,
name: 'eat'
},
{
no: 20,
name: 'swim'
}
];
if i have the user pick no in arrays : [3,3,3,3,3,3,3,3,3,3,3,90,20,20,20,20]
so the output should be an array
[
{
num: 3,
total: 11
},
{
num: 90,
total: 1
},
{
num:20,
total: 4
}
];
I would like to know how to do this with a for/of loop
Here is the code I've attempted:
let obj = [];
for (i of arr){
for (j of data){
let innerObj={};
innerObj.num = i
obj.push(innerObj)
}
}
const data = [{"no":3,"name":"drink"},{"no":90,"name":"eat"},{"no":20,"name":"swim"}];
const arr = [3,3,3,3,3,3,3,3,3,3,3,20,20,20,20,80,80];
const lookup = {};
// Loop over the duplicate array and create an
// object that contains the totals
for (let el of arr) {
// If the key doesn't exist set it to zero,
// otherwise add 1 to it
lookup[el] = (lookup[el] || 0) + 1;
}
const out = [];
// Then loop over the data updating the objects
// with the totals found in the lookup object
for (let obj of data) {
lookup[obj.no] && out.push({
no: obj.no,
total: lookup[obj.no]
});
}
document.querySelector('#lookup').textContent = JSON.stringify(lookup, null, 2);
document.querySelector('#out').textContent = JSON.stringify(out, null, 2);
<h3>Lookup output</h3>
<pre id="lookup"></pre>
<h3>Main output</h3>
<pre id="out"></pre>
Perhaps something like this? You can map the existing data array and attach filtered array counts to each array object.
let data = [
{
no: 3,
name: 'drink'
},
{
no:90,
name: 'eat'
},
{
no:20,
name: 'swim'
}
]
const test = [3,3,3,3,3,3,3,3,3,3,3,90,20,20,20,20]
const result = data.map((item) => {
return {
num: item.no,
total: test.filter(i => i === item.no).length // filters number array and then checks length
}
})
You can check next approach using a single for/of loop. But first I have to create a Set with valid ids, so I can discard noise data from the test array:
const data = [
{no: 3, name: 'drink'},
{no: 90, name: 'eat'},
{no: 20, name: 'swim'}
];
const userArr = [3,3,3,3,3,3,3,3,7,7,9,9,3,3,3,90,20,20,20,20];
let ids = new Set(data.map(x => x.no));
let newArr = [];
for (i of userArr)
{
let found = newArr.findIndex(x => x.num === i)
if (found >= 0)
newArr[found].total += 1;
else
ids.has(i) && newArr.push({num: i, total: 1});
}
console.log(newArr);
How do I join arrays with the same property value? I cannot map it because it has different indexes.
var array1 = [
{'label':"label1",'position':0},
{'label':"label3",'position':2},
{'label':"label2",'position':1},
];
var array2 = [
{'label':"label1",'value':"TEXT"},
{'label':"label2",'value':"SELECT"}
];
expected output:
var array3 = [
{'label':"label1",'value':"TEXT",'position':0},
{'label':"label2",'value':"SELECT", 'position':1}
];
This is what I did, I cannot make it work,
var arr3 = arr1.map(function(v, i) {
return {
"label": v.label,
"position": v.position,
"value": arr2[?].value
}
});
I think you can use array#reduce to do something like this perhaps:
var array1 = [
{'label':"label1",'position':0},
{'label':"label3",'position':2},
{'label':"label2",'position':1},
];
var array2 = [
{'label':"label1",'value':"TEXT"},
{'label':"label2",'value':"SELECT"}
];
var array3 = array2.reduce((arr, e) => {
arr.push(Object.assign({}, e, array1.find(a => a.label == e.label)))
return arr;
}, [])
console.log(array3);
You could take a Map and check the existence for a new object.
var array1 = [{ label: "label1", position: 0 }, { label: "label3", position: 2 }, { label: "label2", position: 1 }],
array2 = [{ label: "label1", value: "TEXT" }, { label: "label2", value: "SELECT" }],
map = array1.reduce((m, o) => m.set(o.label, o), new Map),
array3 = array2.reduce((r, o) => {
if (map.has(o.label)) {
r.push(Object.assign({}, o, map.get(o.label)));
}
return r;
}, []);
console.log(array3);
.as-console-wrapper { max-height: 100% !important; top: 0; }
As per the effort, we take an assumption that array1 will be having all the labels that are in array2.
Based on that first, create a map for array2and with key being labels. Post that, filter out array1 items which have labels existing in the map and then finally merging the objects of the filtered array and its corresponding values in map extracted from array2.
var array1 = [{'label':"label1",'position':0},{'label':"label3",'position':2},{'label':"label2",'position':1}];
var array2 = [{'label':"label1",'value':"TEXT"},{'label':"label2",'value':"SELECT"}];
let map = array2.reduce((a,{label, ...rest}) => Object.assign(a,{[label]:rest}),{});
let result = array1.filter(({label}) => map[label]).map(o => ({...o, ...map[o.label]}));
console.log(result);
Also, in the above snippet, you can improve the performance further by using Array.reduce against filter and map functions to retrieve the result.
var array1 = [{'label':"label1",'position':0},{'label':"label3",'position':2},{'label':"label2",'position':1}];
var array2 = [{'label':"label1",'value':"TEXT"},{'label':"label2",'value':"SELECT"}];
let map = array2.reduce((a,{label, ...rest}) => Object.assign(a,{[label]:rest}),{});
let result = array1.reduce((a,o) => {
if(map[o.label]) a.push({...o, ...map[o.label]});
return a;
}, []);
console.log(result);
If you don't know in advance which array(s) will have their labels be a subset of the other (if any), here's a method that allows for either array1 or array2 to have labels that the other array lacks. Use reduce over array1, finding the matching label in array2 if it exists:
var array1 = [
{'label':"label1",'position':0},
{'label':"label3",'position':2},
{'label':"label2",'position':1},
];
var array2 = [
{'label':"label1",'value':"TEXT"},
{'label':"label2",'value':"SELECT"}
];
const output = array1.reduce((a, { label, position }) => {
const foundValueObj = array2.find(({ label: findLabel }) => findLabel === label);
if (!foundValueObj) return a;
const { value } = foundValueObj;
a.push({ label, value, position });
return a;
}, []);
console.log(output);
See Array.prototype.map() and Map for more info.
// Input.
const A = [{'label':"label1",'position':0},{'label':"label3",'position':2},{'label':"label2",'position':1}]
const B = [{'label':"label1",'value':"TEXT"},{'label':"label2",'value':"SELECT"}]
// Merge Union.
const mergeUnion = (A, B) => {
const mapA = new Map(A.map(x => [x.label, x]))
return B.map(y => ({...mapA.get(y.label), ...y}))
}
// Output + Proof.
const output = mergeUnion(A, B)
console.log(output)
This works.
Approach: Concatenate the objects with same label, using Object.assign()
var array1 = [{'label':"label1",'position':0},{'label':"label3",'position':2},{'label':"label2",'position':1}];
var array2 = [{'label':"label1",'value':"TEXT"},{'label':"label2",'value':"SELECT"}];
var result = [];
array2.forEach(function(value, index){
result.push(Object.assign({},array1.find(function(v,i){return v.label==value.label}),value));
});
console.log(result)
Im not good with javascript,but you could also do this
var array1 = [
{'label':"label1",'position':0},
{'label':"label3",'position':2},
{'label':"label2",'position':1},
];
var array2 = [
{'label':"label1",'value':"TEXT"},
{'label':"label2",'value':"SELECT"}
];
var array3=[];
for(var i=0;i<array1.length;i++)
{
for(var x=0;x<array2.length;x++)
{
console.log(array1[i]['label'] == array2[x]['label']);
if(array1[i]['label'] == array2[x]['label']){
array3.push({label:array1[i]['label'],value:array2[x]['value'],position:array1[i]['position']});
}
}
}
console.log(array3);