Creating a unique array from an array of objects - arrays

My object demoList:
demoList = [
{
id: 1,
validFrom: "2019-06-01T00:00:00",
validTo: "2020-06-17T00:00:00",
xxxM: 50,
xxxN: 2.2,
xxxQ45: 2,
xxxQ100: 1.65,
xxxQ125: null,
xxxQ150: null,
xxxQ250: null,
xxxQ300: null,
xxxQ500: null
},
{
id: 2,
validFrom: "2019-06-01T00:00:00",
validTo: "2020-06-17T00:00:00",
xxxM: 51,
xxxN: 22,
xxxQ45: 1.4,
xxxQ100: 1.65,
xxxQ125: null,
xxxQ150: 1.7,
xxxQ250: null,
xxxQ300: 0.15,
xxxQ500: null,
xxxQ700: 15.4
},
. . .
];
The array I want to obtain:
["M", "N", "45", "100", "150", "300", "700"]
I want an array of non-empty values starting with xxx and found in the demoList list.
How do I do this using angular?

You can .flatMap() your demoList objects to the Object.entries() of each object. You can keep only those entries which start with "xxx" and the value doesn't equal null by using .filter(). You can then map each key to either the last suffix number on the key or the last character of the key using .match(/\d+|\w$/g). You can then put this mapped array into a new Set() to remove any duplicates. Then you can spread ... this set into an array to convert the set back into an array:
const demoList = [{ id: 1, validFrom: "2019-06-01T00:00:00", validTo: "2020-06-17T00:00:00", xxxM: 50, xxxN: 2.2, xxxQ45: 2, xxxQ100: 1.65, xxxQ125: null, xxxQ150: null, xxxQ250: null, xxxQ300: null, xxxQ500: null }, { id: 2, validFrom: "2019-06-01T00:00:00", validTo: "2020-06-17T00:00:00", xxxM: 51, xxxN: 22, xxxQ45: 1.4, xxxQ100: 1.65, xxxQ125: null, xxxQ150: 1.7, xxxQ250: null, xxxQ300: 0.15, xxxQ500: null, xxxQ700: 15.4 } ];
const res = [...new Set(
demoList.flatMap(Object.entries)
.filter(([k, v]) => k.startsWith("xxx") && v !== null)
.map(([k]) => k.match(/\d+|\w$/g).pop())
)];
console.log(res);

Related

How to remove null from object array in php?

I have an arrayof objects like
[
null,
{
"list_type": 1,
"list_item": {
"id": 21,
"name":"aaa"
}
},
null,
null,
{
"list_type": 0,
"list_item": {
"id": 24,
"name":"bbb"
}
}
]
I want to remove the null values from this. I have used array_filter() but it doesn't work.
How can I achieve this?

Angular 11 - Array mapping undefined

I'm using api to get the response array, I'm trying to map the "id" under the "quiz_records" array but it returns undefined. I think that my code are correct.
This is my attempt.
array
"quizRemarks": [
{
"id": 160,
"user_id": 1,
"quiz_id": 18,
"module_id": 29,
"number_of_correct_answers": 2,
"created_at": "2021-10-15T03:52:52.000000Z",
"updated_at": "2021-10-15T03:52:52.000000Z",
"time_started": null,
"time_finished": null,
"remarks": 1,
"quiz_records": [
{
"id": 27,
"user_scores_id": 160,
"question_id": 2,
"user_answers": "DriverPH",
"remarks_correct_incorrect": "1",
"created_at": null,
"updated_at": null,
"question_text": "What is the name of this application?"
},
{
"id": 28,
"user_scores_id": 160,
"question_id": 2,
"user_answers": "Red",
"remarks_correct_incorrect": "1",
"created_at": null,
"updated_at": null,
"question_text": "What traffic light color tells you to stop before the intersection?"
}
]
}
]
ts
this.quiz_records = res['quizRemarks'].map(res => res['quiz_records'].id);
console.log(this.quiz_records);
quizRemarks is an array of objects containing an array of quiz_records. Try this to get a flat list of ids of quiz_records:
this.quiz_records = [];
this.quizRemarks.forEach(remark => {
this.quiz_records.push(...remark.quiz_records.map(rec => rec.id));
});
Below code will work----
this.quiz_records = res['quizRemarks'].map(res => res['quiz_records'].map(r => r.id));
You're truing to get an id property from an array, what it inpossible.
You can use nested map + flat() array method.
const result = res['quizRemarks'].map(remarks => {
return remarks['quiz_records'].map(record => record.id);
}).flat();

Key value pair string generation out of an array React JS

I have following array (foodDetailsList)
[{"food_id": 5, "quantity": 100, "quantity_unit": gm},
{"food_id": 45, "quantity": 200, "quantity_unit": gm},
{"food_id": 22, "quantity": 300, "quantity_unit": gm}]
Out of which, I wish to create following variable String as an OUTPUT:
'food[0][food_id]': '5',
'food[0][quantity]': '100',
'food[0][quantity_unit]': 'gm',
'food[1][food_id]': '45',
'food[1][quantity]': '200',
'food[1][quantity_unit]': 'gm',
'food[2][food_id]': '45',
'food[2][quantity]': '200',
'food[2][quantity_unit]': 'gm'
I wanted to try something like following:
const createString = ()=>{
let finalFoodList =[];
foodDetailsList.map((food,key) =>{
finalFoodList.push({
'food['+[key]+'][food_id]'`:food.id,
'food['+[key]+'][quantity]'`:food.quantity
});
});
console.log("final variable is : ",finalFoodList.toString);
}
Need to improve above code syntatically so that above output is received.
You can use the map function to iterate over your original array, then use Object.keys to get all keys of the contained food-objects and map over those keys as well to get a generic solution like this:
const foodList = [
{"food_id": 5, "quantity": 100, "quantity_unit": 'gm'},
{"food_id": 45, "quantity": 200, "quantity_unit": 'gm'},
{"food_id": 22, "quantity": 300, "quantity_unit": 'gm'}]
const foodString = foodList.map((food, index) =>
Object.keys(food).map(key => `'food[${index}][${key}]': '${food[key]}'`).join('\n')
).join('\n');
console.log(foodString);
The join()-Method joins all array-members as string with linebreaks as separators.
You can use .map() on your arr of objects. For each object you can destructure it to obtain the food_id, quantity and quantity_unit properties. Based on that, you can return a string in the format which you desired, using the index i provided in the .map() callback as the index for food in your string. Once you have obtained an array of strings, you can join each string using .join('\n').
See example below:
const arr = [{"food_id": 5, "quantity": 100, "quantity_unit": 'gm'},
{"food_id": 45, "quantity": 200, "quantity_unit": 'gm'},
{"food_id": 22, "quantity": 300, "quantity_unit": 'gm'}];
const res = arr.map(({food_id, quantity, quantity_unit}, i) =>
`'food[${i}][food_id]': '${food_id}'\n'food[${i}][quantity]': '${quantity}'\n'food[${i}][quantity_unit]': '${quantity_unit}'`
).join('\n');
console.log(res);
try this:
const foodList = [
{"food_id": 5, "quantity": 100, "quantity_unit": gm},
{"food_id": 45, "quantity": 200, "quantity_unit": gm},
{"food_id": 22, "quantity": 300, "quantity_unit": gm}
];
const createString = () => {
const foodLen = foodList.length;
let finalFoodList = foodList.map((food, index) => {
return index !== foodLen ? (
`'food[${index}][food_id]': '${food.food_id}',\n
'food[${index}][quantity]': '${food.quanatity}',\n
'food[${index}][quantity_unit]': '${food.quantity_unit}',\n`
) : (
`'food[${index}][food_id]': '${food.food_id}',\n
'food[${index}][quantity]': '${foof.quanatity}',\n
'food[${index}][quantity_unit]': '${food.quantity_unit}'
);
});
}
get length of foodList array.
map function creates new array.
second parameter in map function gives current iteration number.
we use ternary operator to return conditional output.

How to merge multiple dynamic arrays and store it in another array using angular 2?

I am getting multiple arrays dynamically. I need to take pk_location_id from those arrays. But the arrays are not merged, so I am facing issue in taking pk_location_id from those arrays.
I am getting arrays as follows:
Array(2)
0:{pk_location_id: 3, tenant_id: null, locationname: "Karnataka", locationpath: null, location_phone: null, …}
1:{pk_location_id: 4, tenant_id: null, locationname: "Maharashtra", locationpath: null, location_phone: "9876543211", …}
length:2
Array(3)
0:{pk_location_id: 5, tenant_id: null, locationname: "banglore", locationpath: null, location_phone: "444444444", …}
1:{pk_location_id: 8, tenant_id: null, locationname: "Mysore", locationpath: "/Karnataka/India/HTL", location_phone: "9888888888", …}
2:{pk_location_id: 9, tenant_id: null, locationname: "Hubli", locationpath: "/Karnataka/India/HTL", location_phone: "876543212", …}
length:3
Array(1)
0:{pk_location_id: 6, tenant_id: null, locationname: "jay nagar", locationpath: "/banglore/Karnataka/India/HTL", location_phone: null, …}
length:1
Array(1)
0:{pk_location_id: 7, tenant_id: null, locationname: "puna", locationpath: "", location_phone: null, …}
length:1
I tried to merge these arrays using concat and push but that did not work.
I tried as follows:
const mergedarray = [].concat(...this.locations);
this.locationIds.push(...this.locations);
How to fetch pk_location_id from these arrays and store it in to another array?
I am getting the HTTP response as follows:
response
After getting the response I am filtering it.
The code is as follows:
this.locationFilteredList = this.allLocationArray[0].filter(
(book:Location) => book.parent_location_id === parent_location_id);
this.locations = this.locationFilteredList;
Can anyone please provide solution for this?
Thanks & Regards
Shilpa Kulkarni
Let me give you a sample idea
let arr1 = [{pk_location_id: 3}, {pk_location_id: 2}];
let arr2 = [{pk_location_id: 3}, {pk_location_id: 2}];
let arr3 = [{pk_location_id: 3}, {pk_location_id: 2}];
let combinedArr = [].concat(arr1, arr2, arr3);
for(let locId in combinedArr){
console.log(locId.pk_location_id);// do whatever you want to do
}

Combining multiple arrays into one, indexing sequentially

I have multiple array (max 15), each can max have 1800 objects.
I need to combine them into a single array, so that I then can apply a delimiter (',') to generate a csv file. The problem is when I combine them into a single array, it has to be sequentially combined, like first objects of each array should be inserted initially followed by the 2nd index of objects then 3rd and so on.
I'm able to achieve the result I want by using a for-in loop. However this doesn't very swifty. I feel it can be done in a much cleaner way using functional methods available in swift (using map, reduce and filter functions).
However I'm not able to combine them perfectly. Can anyone help me with using the swift functional methods to achieve the result.
P.S: Let me know if you want me to post the for-in loop code, but I believe that's not required.
Given 4 (or more) arrays
let list0: [Int] = [ 1, 2, 3, 6, 7, 8, 9 ]
let list1: [Int] = [ 10, 20, 30, 40, 50, 60, 70, 80, 90]
let list2: [Int] = [ 100, 200, 300, 400, 500, 600, 700, 800, 900]
let list3: [Int] = [ 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000 ]
enumerate each one and put them into another array
let lists = [
list0.enumerate().map { (index: $0, array: 0, value: $1) },
list1.enumerate().map { (index: $0, array: 1, value: $1) },
list2.enumerate().map { (index: $0, array: 2, value: $1) },
list3.enumerate().map { (index: $0, array: 3, value: $1) }
]
Now you can write
let sorted = lists
.flatten()
.sort { ($0.index, $0.array) < ($1.index, $1.array) }
.map { $0.value }
[1, 10, 100, 1000, 2, 20, 200, 2000, 3, 30, 300, 3000, 6, 40, 400, 4000, 7, 50, 500, 5000, 8, 60, 600, 6000, 9, 70, 700, 7000, 80, 800, 8000, 90, 900, 9000]
I would consider making this an extension for arrays of arrays (although note you cannot do this directly, see this Q&A). You could then use a combination of reduce(_:_:) along with both flavours of flatMap(_:) in order to sequentially merge your arrays by iterating through the lengths of the inner collections and extracting the elements at each given index.
extension Array where Element : RandomAccessCollection, Element.Index == Int, Element.IndexDistance == Element.Index {
func joinedByTransposing() -> [Element.Iterator.Element] {
// The maximum length of the inner collections. Obviously if the 2D array is
// guaranteed to be n*m, you can optimise by just taking the first inner
// collection's count (and obviously you'll want to check that the array isn't empty first).
let maxIndex = self.reduce(0, {$0 > $1.count ? $0 : $1.count})
// Iterates through the max length of the inner collections, joining the restantant collections
// from the transform below into a single array.
return (0..<maxIndex).flatMap { index in
// Iterate through each inner collection, getting the element at the current index of iteration,
// or returning nil if the index is out of bounds. This flatMap will filter out any nils.
// If the 2D array is guarenteed to be n*m, this can be replaced by self.map { $0[index] }
self.flatMap { innerArray in
// Simple bounds check to get the element at the given index, or nil if out of bounds
index < innerArray.count ? innerArray[index] : nil
}
}
}
}
let array0 = [1, 2, 3, 4 ]
let array1 = [10, 20, 30 ]
let array2 = [100, 200, 300, 6, 7]
let result = [array0, array1, array2].joinedByTransposing()
print(result)
// [1, 10, 100, 2, 20, 200, 3, 30, 300, 4, 6, 7]
It’s worth noting that this solution has an overall time complexity of O(n * m) – whereas solutions that utilise sorted(by:) will have a time complexity of at least O(n * m * log(n * m)). For large arrays, this extra cost may well be non-trivial.
Here is my functional approach to the problem that you describe in your post.
First I flatted the array using the enumerated method, which return a tuple with the element position inside the array and It's value.
After this, You have an array with this tuples, next step, sort this big array by the offset (position) value of each element.
Once the array is sorted you hace to extract the value with map function.
And final step, once we have an array with sorted values, You have to reduce it to a string with the reduce function
// A group of arrays
var array1: [Int] = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
var array2: [Int] = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
var array3: [Int] = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
var array4: [Int] = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
// This is **your** array
let bigOne = [ array1, array2, array3, array4 ]
// And here is the functional concatenation.
let flattedOne = bigOne.flatMap({ $0.enumerated() }).sorted(by: { $0.0 < $0.1 }).map({$0.element}).reduce("")
{
return $0.isEmpty ? "\($1)" : "\($0), \($1)"
}
print(flattedOne)
Here's another approach...
public func sort(compound array: [[Int]]) -> [Int]
{
let max_index: Int = array.map({ $0.count }).max()!
var sorted: [Int] = [Int]()
(0 ..< max_index).forEach({ index in
array.forEach()
{
if $0.count > index
{
sorted.append($0[index])
}
}
})
return sorted
}
// A group of arrays
var array1: [Int] = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111, 112 ]
var array2: [Int] = [ 10, 20, 3, 4, 5, 6, 7, 8, 9, 10 ]
var array3: [Int] = [ 1000, 2000, 3, 4, 5, 600, 7, 8, 9, 10, 11 ]
var array4: [Int] = [ 100, 200, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
let bigOne: [[Int]] = [ array1, array2, array3, array4 ]
let sorted: [Int] = sort(compound: bigOne)
print(sorted)
And if you want the array as a CSV string...
print(sorted.reduce("") { return $0.isEmpty ? "\($1)" : "\($0), \($1)" })

Resources