I have a json like below and have a requirement to add values in it
{ "10 days refund": [
{
"paymentType": "CreditCard",
"amount": "40$",
"expiryDate": "20/10/2025"
},
{
"paymentType": "CreditCard",
"amount": "20$",
"expiryDate": "20/1/2024"
}
],
"3 hours refund": [
{
"paymentType": "DebitCard",
"amount": "10$",
"expiryDate": "20/10/2026"
},
{
"paymentType": "DebitCard",
"amount": "5$",
"expiryDate": "20/10/2027"
}
]
}
In the above map, I would need to add a field "message" to last value of each category of map. So after adding the value I'm expecting the resultant map like below
{ "10 days refund": [
{
"paymentType": "CreditCard",
"amount": "40$",
"expiryDate": "20/10/2025"
},
{
"paymentType": "CreditCard",
"amount": "20$",
"expiryDate": "20/1/2024",
"message" : "Refund will be processed in 10 days"
}
],
"3 hours refund": [
{
"paymentType": "DebitCard",
"amount": "10$",
"expiryDate": "20/10/2026"
},
{
"paymentType": "DebitCard",
"amount": "5$",
"expiryDate": "20/10/2027",
"message" : "Refund will be processed in 3 hours"
}
]
}
I have tried implementing it using below method
(defn ^:private payment-methods
[pm-sorted]
(let [categories (group-by pm-fingerprint pm-sorted)]
(for [[pm-fingerprint pm-sorted] categories
:let [last-payment-method (last pm-sorted)
dropped-last (drop-last pm-sorted)]]
(if (= (:refund-category pm-fingerprint) "10 hours refund")
((println "10 days refund")
(doall (conj (doall dropped-last) (assoc last-payment-method :message
(text (str "Refund will be processed in 10 days"))))))
((println "3 hours refund")
(doall (conj (doall dropped-last) (assoc last-payment-method :message
(text (str "Refund will be processed in 3 hours"))))))))))
(defn ^:private pm-fingerprint
[payment-method]
(let [payment-type ("paymentType" payment-method)]
{:refund-category (if (= payment-type "CreditCard"))
"10 days refund"
"3 hours refund")}))
I expect the resultant output by executing the function to be a vector like below
[
{
"paymentType": "CreditCard",
"amount": "40$",
"expiryDate": "20/10/2025"
},
{
"paymentType": "CreditCard",
"amount": "20$",
"expiryDate": "20/1/2024",
"message" : "Refund will be processed in 10 days"
}
{
"paymentType": "DebitCard",
"amount": "10$",
"expiryDate": "20/10/2026"
},
{
"paymentType": "DebitCard",
"amount": "5$",
"expiryDate": "20/10/2027",
"message" : "Refund will be processed in 3 hours"
}
]
And I get null as the output as no value is returned. Can someone please help wrt the issue ?
Here is an example that works. First, declarations & data:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[schema.core :as s]
[tupelo.string :as str]
))
(def input
(str/quotes->double
"{ '10-days-refund': [
{ 'paymentType': 'CreditCard',
'amount': '40$',
'expiryDate': '20/10/2025' },
{ 'paymentType': 'CreditCard',
'amount': '20$',
'expiryDate': '20/1/2024' }
],
'3-hours-refund': [
{
'paymentType': 'DebitCard',
'amount': '10$',
'expiryDate': '20/10/2026' },
{ 'paymentType': 'DebitCard',
'amount': '5$',
'expiryDate': '20/10/2027' } ] }"))
Then the processing:
(dotest
(let [data (json->edn input)
data2 (vec
(for [entry data]
(let [[the-key pmt-lst] entry ; destruture into key and list of vals
pmt-lst-butlast (butlast pmt-lst)
pmt-lst-last (last pmt-lst)
last-new (assoc pmt-lst-last :message "Coming Soon!")
pmt-lst-new (append pmt-lst-butlast last-new)
entry-new [the-key pmt-lst-new]]
entry-new)))]
and the result verified:
(is= data2
[[:10-days-refund
[{:amount "40$" :expiryDate "20/10/2025" :paymentType "CreditCard"}
{:amount "20$"
:expiryDate "20/1/2024"
:message "Coming Soon!"
:paymentType "CreditCard"}]]
[:3-hours-refund
[{:amount "10$" :expiryDate "20/10/2026" :paymentType "DebitCard"}
{:amount "5$"
:expiryDate "20/10/2027"
:message "Coming Soon!"
:paymentType "DebitCard"}]]]
)))
Please see the list of documentation in this template project, especially the Clojure CheatSheet.