remove key of matched number in [String:[NSNumber]] - arrays

How to remove a value from dictionary with array of values. I have response from server like below:
[
"business_proof":[
0,
0,
0,
0,
0,
0,
0,
0,
-1,// business_proof contains -1, I want to remove this key like wise any other contains
0,
0
],
"reference_proof":[
1,
2,
1
],
"vehicle_proof":[
1,
1,
2
],
"previous_loan_track":[
2,
2,
0,
0,
2,
2
],
"banking_proof":[
1,
1
],
"income_proof":[
0,
0,
2,
0,
2,
1,
2,
0,
0
],
"signature_proof":[
2,
2,
1,
2,
2,
2
],
"employment_proof":[
2,
1,
2,
2,
2,
2,
2
],
"guarantor_proof":[
1,
2,
2
],
"pdc_proof":[
1,
0
],
"address_proof":[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
3
],
"age_proof":[
2,
2,
2,
2,
2,
2,
1,
2
],
"contact_proof":[
0,
2,
2
],
"photo_id_proof":[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
]
Second reponse
[
"signature_proof":[
"pan_card",
"driving_licence",
"accepted_documents",
"passport",
"cancelled_cheque",
"bank_report"
],
"guarantor_proof":[
"accepted_documents",
"co_applicant",
"guarantor"
],
"previous_loan_track":[
"housing_loan",
"vehicle_loan",
"over_draft_limit",
"accepted_documents",
"business_loan",
"personal_loan"
],
"address_proof":[
"bank_statement",
"voter_id",
"rental_agreement",
"eb_bill",
"registration_document",
"hr_letter",
"driving_licence",
"property_tax_receipt",
"telephone_bill",
"cc_statement",
"gas_bill",
"aadhaar_card",
"passport",
"ration_card",
"accepted_documents"
],
"vehicle_proof":[
"vehi_insurance",
"vehi_rc",
"accepted_documents"
],
"business_proof":[
"business_commencement_certificate",
"ssi_msme_certificate",
"business_transactions",
"mou",
"aoa",
"gst_no",
"tan_no",
"business_agreements",
"accepted_documents",
"shop_and_establishment_certificate",
"incorporation_certificate"
],
"banking_proof":[
"bank_statement",
"accepted_documents"
],
"income_proof":[
"form_16",
"profit_loss_statement",
"rental_income_proof",
"payslip",
"income_in_cash_proof",
"accepted_documents",
"brokerage_income_proof",
"it_returns",
"audited_balance_sheet"
],
"reference_proof":[
"ref2",
"accepted_documents",
"ref1"
],
"employment_proof":[
"employee_id_card",
"accepted_documents",
"payslip",
"relieving_letter",
"comp_app_letter",
"hr_letter",
"epf_no_uan_no"
],
"age_proof":[
"employee_id_card",
"ration_card",
"pan_card",
"passport",
"voter_id",
"school_certificate",
"accepted_documents",
"aadhaar_card"
],
"contact_proof":[
"accepted_documents",
"landline_bill",
"mobile_bill"
],
"photo_id_proof":[
"employee_id_card",
"nrega_card",
"ration_card",
"bank_passbook",
"pan_card",
"passport",
"voter_id",
"driving_licence",
"accepted_documents",
"aadhaar_card"
],
"pdc_proof":[
"cheque_book",
"accepted_documents"
]
]
Both are array of dictionary, Both will have same key only. I know this structure is completely wrong.
business_proof only contains - 1, so i want to remove both places.
Here i need to remove key and values if anyone key values contains -1.
I am trying like this but it shows compiler error
finalValueArray.removeAll(where: { $0.contains(-1) })

You can use filter as far as I understand
var filteredItems = object.filter { !$0.value.contains(-1)}
You can get all elements which contain -1
var minusOneItems = object.filter { $0.value.contains(-1)}
and than
for negativeItem in minusOneItems {
object.removeValue(forKey: negativeItem.key)
}
It depends what you need.

You can simply use a combination of forEach and contains on the dictionary like so,
var dictionary = ["business_proof": [0, 0, 1, -1, 2, -1], "reference_proof": [1, 2, 1], "vehicle_proof": [-1, 0, 0, 2]]
dictionary.forEach { (key,value) in
dictionary[key] = value.contains(-1) ? nil : value
}
print(dictionary) //["reference_proof": [1, 2, 1]]
Or you can simply apply filter on dictionary like,
dictionary = dictionary.filter({ !$0.value.contains(-1) })
print(dictionary) //["reference_proof": [1, 2, 1]]

You can filter your dictionary to remove the entries that contains -1 in their value.
let filteredArrayOnDict = dataDict.filter { value.contains{ $0 != -1 } }
The filteredArrayOnDict is the array of tuples. Now if you want to create a dictionary from it. You can do this way:
let filteredDictionary = filteredArrayOnDict.reduce(into: [:]) { $0[$1.0] = $1.1}
Now you have the only the entries in filteredDictionary that doesn't have -1 in their value.

You can use while loop to remove all key-value pairs which contain -1 from both dictionaries.
var dict1 = ["business_proof":[0,0,0,0,0,0,0,0,-1,0,0],"reference_proof":[1,2,1],"vehicle_proof":[1,1,2],"previous_loan_track":[2,2,0,0,2,2],"banking_proof":[1,1],"income_proof":[0,0,2,0,2,1,2,0,0],"signature_proof":[2,2,1,2,2,2],"employment_proof":[2,1,2,2,2,2,2],"guarantor_proof":[1,2,2],"pdc_proof":[1,0],"address_proof":[2,2,2,2,2,2,2,2,2,2,2,2,2,2,3],"age_proof":[2,2,2,2,2,2,1,2],"contact_proof":[0,2,2],"photo_id_proof":[2,2,2,2,2,2,2,2,2,2]]
var dict2 = ["signature_proof":["pan_card","driving_licence","accepted_documents","passport","cancelled_cheque","bank_report"],"guarantor_proof":["accepted_documents","co_applicant","guarantor"],"previous_loan_track":["housing_loan","vehicle_loan","over_draft_limit","accepted_documents","business_loan","personal_loan"],"address_proof":["bank_statement","voter_id","rental_agreement","eb_bill","registration_document","hr_letter","driving_licence","property_tax_receipt","telephone_bill","cc_statement","gas_bill","aadhaar_card","passport","ration_card","accepted_documents"],"vehicle_proof":["vehi_insurance","vehi_rc","accepted_documents"],"business_proof":["business_commencement_certificate","ssi_msme_certificate","business_transactions","mou","aoa","gst_no","tan_no","business_agreements","accepted_documents","shop_and_establishment_certificate","incorporation_certificate"],"banking_proof":["bank_statement","accepted_documents"],"income_proof":["form_16","profit_loss_statement","rental_income_proof","payslip","income_in_cash_proof","accepted_documents","brokerage_income_proof","it_returns","audited_balance_sheet"],"reference_proof":["ref2","accepted_documents","ref1"],"employment_proof":["employee_id_card","accepted_documents","payslip","relieving_letter","comp_app_letter","hr_letter","epf_no_uan_no"],"age_proof":["employee_id_card","ration_card","pan_card","passport","voter_id","school_certificate","accepted_documents","aadhaar_card"],"contact_proof":["accepted_documents","landline_bill","mobile_bill"],"photo_id_proof":["employee_id_card","nrega_card","ration_card","bank_passbook","pan_card","passport","voter_id","driving_licence","accepted_documents","aadhaar_card"],"pdc_proof":["cheque_book","accepted_documents"]]
while let invalid = dict1.first(where: { $0.value.contains(-1) }) {
dict1.removeValue(forKey: invalid.key)
dict2.removeValue(forKey: invalid.key)
}
print(dict1)//["reference_proof":[1,2,1],"vehicle_proof":[1,1,2],"previous_loan_track":[2,2,0,0,2,2],"banking_proof":[1,1],"income_proof":[0,0,2,0,2,1,2,0,0],"signature_proof":[2,2,1,2,2,2],"employment_proof":[2,1,2,2,2,2,2],"guarantor_proof":[1,2,2],"pdc_proof":[1,0],"address_proof":[2,2,2,2,2,2,2,2,2,2,2,2,2,2,3],"age_proof":[2,2,2,2,2,2,1,2],"contact_proof":[0,2,2],"photo_id_proof":[2,2,2,2,2,2,2,2,2,2]]
print(dict2)//["signature_proof":["pan_card","driving_licence","accepted_documents","passport","cancelled_cheque","bank_report"],"guarantor_proof":["accepted_documents","co_applicant","guarantor"],"previous_loan_track":["housing_loan","vehicle_loan","over_draft_limit","accepted_documents","business_loan","personal_loan"],"address_proof":["bank_statement","voter_id","rental_agreement","eb_bill","registration_document","hr_letter","driving_licence","property_tax_receipt","telephone_bill","cc_statement","gas_bill","aadhaar_card","passport","ration_card","accepted_documents"],"vehicle_proof":["vehi_insurance","vehi_rc","accepted_documents"],"banking_proof":["bank_statement","accepted_documents"],"income_proof":["form_16","profit_loss_statement","rental_income_proof","payslip","income_in_cash_proof","accepted_documents","brokerage_income_proof","it_returns","audited_balance_sheet"],"reference_proof":["ref2","accepted_documents","ref1"],"employment_proof":["employee_id_card","accepted_documents","payslip","relieving_letter","comp_app_letter","hr_letter","epf_no_uan_no"],"age_proof":["employee_id_card","ration_card","pan_card","passport","voter_id","school_certificate","accepted_documents","aadhaar_card"],"contact_proof":["accepted_documents","landline_bill","mobile_bill"],"photo_id_proof":["employee_id_card","nrega_card","ration_card","bank_passbook","pan_card","passport","voter_id","driving_licence","accepted_documents","aadhaar_card"],"pdc_proof":["cheque_book","accepted_documents"]]
Create a struct and initialize the struct objects with both dictionary values. Then store the struct objects in an array. Now you can filter the array by its values
struct Proof {
var title: String
var arr: [Int]
var documents: [String]
}
var proofs = [Proof]()
dict1.forEach {
if let docs = dict2[$0.key] {
proofs.append(Proof(title: $0.key, arr: $0.value, documents: docs))
}
}
print(proofs)
let validProofs = proofs.filter { !$0.arr.contains(-1) }
print(validProofs)

Enumerate the index dictionary, look for occurrences of -1 and filter the indices. Then reverse the found indices and remove the items in both arrays. The code considers that both dictionaries are value types
var indexDict = ["business_proof":[0,0,0,0,0,0,0,0,-1,0,0] ...
var valueDict = ["signature_proof":["pan_card","driving_licence","accepted_documents","passport","cancelled_cheque","bank_report"] ...
for (key, value) in indexDict {
let foundIndices = value.indices.filter({value[$0] == -1})
for index in foundIndices.reversed() {
indexDict[key]!.remove(at: index)
valueDict[key]!.remove(at: index)
}
}

Related

MongoDB - aggregation - How to group, concatenate arrays, sum integer field in a single step

I have a collection called 'session_list' with the following rows.
{"user_id":"test#gmail.com","focus_score":[1, 2, 3, 4],"active_score":[3, 4, 1], "score" : 10}
{"user_id":"abcd#gmail.com","focus_score":[3, 4],"active_score":[3, 4, 1, 7, 7], "score" : 3}
{"user_id":"test#gmail.com","focus_score":[1, 2, 3, 4, 7],"active_score":[3, 9, 2], "score" : 7}
{"user_id":"abcd#gmail.com","focus_score":[5, 7, 8],"active_score":[1, 3, 7], "score" : 4}
How do I group by user_id and consolidate the focus_score array and then active_score array (without having any for loops) ?
Expected result:
{"user_id":"test#gmail.com","focus_score":[1, 2, 3, 4, 1, 2, 3, 4, 7], "active_score":[3, 4, 1, 3, 9, 2], "score_sum" : 17}
{"user_id":"abcd#gmail.com","focus_score":[3, 4, 5, 7, 8], "active_score":[3, 4, 1, 7, 7, 1, 3, 7], "score_sum" : 7}
My code:
db.session_list.aggregate([
{
$group: {
_id:{user_id:'$user_id'},
focus_score:{$push:'$focus_score'}
active_score:{$push:'$active_score'}
score_sum:{$sum:'$score_sum'}
}
}
])
But this does not provide the expected result.
db.collection.aggregate([
{
$group: {
_id: "$user_id",
focus_score: { $push: "$focus_score" },
active_score: { $push: "$active_score" },
score_sum: { $sum: "$score" }
}
},
{
$project: {
_id: 0,
score_sum: 1,
user_id: "$_id",
focus_score: {
$reduce: {
input: "$focus_score",
initialValue: [],
in: { $concatArrays: [ "$$value", "$$this" ] }
}
},
active_score: {
$reduce: {
input: "$active_score",
initialValue: [],
in: { $concatArrays: [ "$$value", "$$this" ] }
}
}
}
}
])
mongoplayground

How to create 2D array dynamically with the ES6 approach?

I've been trying to create 2D arrays from an array dynamically with a function; however, I couldn't break out of the ES3 old school approach. Does anybody know how to refactor the following code using the ES6 approach?
const nums = [1,2,3,4,5,6,7,8,9,10,11,12];
const letters = ['a','b','c','d','e','f','g','h','i'];
function create2D(arr,set) {
const result = [];
for (let i = 0; i < arr.length; i+=set) {
const rows = arr.slice(i,i+set);
result.push(rows);
}
return result;
}
console.log(create2D(nums,4)); // [ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9, 10, 11, 12 ] ]
console.log(create2D(letters,3)); // [ [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ], [ 'g', 'h', 'i' ] ]
I've only gotten this far with "reduce" and couldn't find out how to replicate the addition assignment "i+=set" from the for loop. This is what I have so far...
function create2D(arr,set) {
return arr.reduce((result,item,i) => {
result.push(arr.slice(i,i+set));
return result;
},[]);
}
console.log(create2D(nums, 4)); // [ [1, 2, 3, 4],[2, 3, 4, 5],[3, 4, 5, 6], ...]
You were pretty close. Just need to modify it slightly:
const nums = [1,2,3,4,5,6,7,8,9,10,11,12];
const letters = ['a','b','c','d','e','f','g','h','i'];
function create2D(arr,set) {
return arr.reduce((result,item,i) => {
let startVal = i*set //We want to jump through the startPoints. Not iterate through them all
if (startVal < arr.length-1) {
result.push(arr.slice(startVal,startVal+set));
}
return result;
}, []);
}
console.log(create2D(nums, 4)); // [ [1, 2, 3, 4],[2, 3, 4, 5],[3, 4, 5, 6], ...]
console.log(create2D(nums, 3));
console.log(create2D(letters, 3));

How to iterate through an array of objects in ruby

I have this array right here and I need to get the "id" of each object
[{ id: 1, points: 60 }, { id: 2, points: 20 }, { id: 3, points: 95 }, { id: 4, points: 75 }]
customers = [{ id: 1, points: 90 }, { id: 2, points: 20 }, { id: 3, points: 70 }, { id: 4, points: 40 }, { id: 5, points: 60 }, { id: 6, points: 10}]
I know how to go through the whole array with
#scores.each_with_index{ |score, index| }
However, I haven't found a way to get the objects's points.
Perhaps you are looking for the following.
customers = [
{ id: 1, points: 90 }, { id: 2, points: 20 },
{ id: 3, points: 70 }, { id: 4, points: 40 },
{ id: 5, points: 60 }, { id: 6, points: 10}
]
h = customers.each_with_object({}) do |g,h|
id, points = g.values_at(:id, :points)
h[id] = points
end
#=> {1=>90, 2=>20, 3=>70, 4=>40, 5=>60, 6=>10}
This allows you to easily extract information of interest, such as the following.
h.keys
#=> [1, 2, 3, 4, 5, 6]
h.values
#=> [90, 20, 70, 40, 60, 10]
h[2]
#=> 20
h.key?(5)
#=> true
h.key?(7)
#=> false
h.value?(70)
#=> true
h.value?(30)
#=> false
What you called score is actually an hash like { id: 1, points: 60 } and I'm going to call it item
So, let's try
#scores.each_with_index do |item, index|
puts "#{index + 1}: id #{item[:id]}, points #{item[:points]}"
end
So, I have this array right here and I need to get the id of each object
In order to transform each element of a collection, you can use Enumerable#map (or in this case more precisely Array#map):
customers.map { _1[:id] }
#=> [1, 2, 3, 4, 5, 6]
This given construct is an array of objects so we need to individually iterate through each element and print out the value present in the objects. The following code shows how we can do it:
customers.each{|obj| p obj[:id].to_s+" "+ obj[:points].to_s }
Here we iterate through each element and print out individual entities of the hash using the obj[:id]/obj[:points] (obj being each individual object here.)
What about something like this?
customers.map(&:to_proc).map{ |p| [:id, :points].map(&p) }
=> [[1, 90], [2, 20], [3, 70], [4, 40], [5, 60], [6, 10]]

How to get every permutation of elements in an array of arrays

I have an array of arrays in TypeScript. I would like to take action on every permutation of elements between the inner arrays.
Here is an example:
const arrOfArrays = [
[1],
[2, 3, 4],
[5, 6],
[7, 8]
];
recursePermutations(arrOfArrays, permutation => {
console.log(permutation);
});
And when I run this, I would like to have the following output:
[ 1, 2, 5, 7 ]
[ 1, 2, 5, 8 ]
[ 1, 2, 6, 7 ]
[ 1, 2, 6, 8 ]
[ 1, 3, 5, 7 ]
[ 1, 3, 5, 8 ]
[ 1, 3, 6, 7 ]
[ 1, 3, 6, 8 ]
[ 1, 4, 5, 7 ]
[ 1, 4, 5, 8 ]
[ 1, 4, 6, 7 ]
[ 1, 4, 6, 8 ]
It should call the permutation callback with the number of elements as there are non-empty inner arrays.
I see questions regarding how to find all permutations of elements in a fixed number of arrays. But in this case, I don't know how many inner arrays are present.
As I hinted in the question, here is a solution that uses recursion and generics:
function recursePermutations<T>(arrOfArrays: T[][], callback: (permutation: T[]) => void, i: number = 0, previousElements: T[] = []) {
if (i < arrOfArrays.length) {
const currentElements = arrOfArrays[i];
for (var element of currentElements) {
recursePermutations(arrOfArrays, callback, i + 1, previousElements.concat(element));
}
if (currentElements.length < 1) {
recursePermutations(arrOfArrays, callback, i + 1, Array.from(previousElements));
}
}
else if (previousElements.length > 0) {
callback(previousElements);
}
}
It handles the case of the outer array not having any inner arrays by not calling the callback.
It also handles the case of one or more of the inner arrays having zero elements. In that case, it calls the permutation callback with only the number of elements as there are non-empty inner arrays.

How to extract integer values from Array (of mixed types: integers/strings) via RegExp?

I have an array:
arr2 = [6, '(7,0)', '(15,0)', '(5,0)', 3, '(15,2)', 17]
I want to parse each element of the array and get the value as follows:
arr2 = [6, 0, 0, 0, 3, 2, 17]
means if the array element is like (15,2) then only the second element i.e 2 should get printed in the response, and if the array element is not in the format like (7,0) then it should be printed as it is.
arr = [6, '(7,0)', '(15,0)', '(5,0)', 3, '(15,2)', 17]
arr.map do |obj|
case obj
when Integer
obj
else
obj[/(?<=,)\d+/].to_i
end
end
#=> [6, 0, 0, 0, 3, 2, 17]
[6, [7,0], [15,0], [5,0], 3, [15,2], 17].map { |e| [*e].last }
#⇒ [6, 0, 0, 0, 3, 2, 17]
If the elements are strings:
%w[6, (7,0), (15,0), (5,0), 3, (15,2), 17].map { |e| e[/\d+(?=\)|,?\z)/] }
#⇒ ["6", "0", "0", "0", "3", "2", "17"]
map(&:to_i) the latter to get an array of integers.
Finally, for the up-to-date version:
[6, '(7,0)', '(15,0)', '(5,0)', 3, '(15,2)', 17].
map { |e| e.to_s[/\d+(?=\)|,?\z)/] }.
map(&:to_i)
#⇒ [6, 0, 0, 0, 3, 2, 17]
Exotics:
[6, '(7,0)', '(15,0)', '(5,0)', 3, '(15,2)', 17].
inspect.
scan(/\d+(?:,\d+)?/).
map { |e| e.split(',').last.to_i }
#⇒ [6, 0, 0, 0, 3, 2, 17]
This seems fine to me:
arr2.map{|x| x.to_s.scan(/\d+/).last.to_i }
And if you want something without regexp:
arr2.map do |item|
item.is_a?(Integer) ? item : item[1+item.rindex(',')..-2].to_i
end

Resources