Reputation: 3409
["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"
Upvotes: 0
Views: 1113
Reputation: 171
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
}
Upvotes: 1
Reputation: 1
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);
Upvotes: 0
Reputation: 27192
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);
Upvotes: 1
Reputation: 5122
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)
Upvotes: 1
Reputation: 33726
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; }
Upvotes: 0