# Help with string mapping from input

**URL:** <https://discourse.julialang.org/t/help-with-string-mapping-from-input/16752>\
**Category:** New to Julia\
**Created:** [October 24, 2018, 6:29pm UTC](https://discourse.julialang.org/t/help-with-string-mapping-from-input/16752 "2018-10-24T18:29:07Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![jonjilla](https://avatars.discourse-cdn.com/v4/letter/j/7ba0ec/32.png) [@jonjilla](https://discourse.julialang.org/u/jonjilla)\
**Post date:** [October 24, 2018, 6:29pm UTC](https://discourse.julialang.org/t/help-with-string-mapping-from-input/16752/1 "2018-10-24T18:29:07Z")

</div>

Hello

I’m trying to import a custom text file that isn’t well aligned and a mixture of data types.

The input data looks something like this

```julia
inputtext = ["ABC=1,2,3,cats,dogs","DEF=1,apples,oranges,4,5,6.78,bananas","XYZ=Julia,R,Python,9.9999"]

```

Currently, my code is very brute force manual and I was hoping that there was a better way to generate this, perhaps with some sort of mapping function

```julia
ABC = DataFrame(a=Int64[],b=Int64[],c=Int64[],animal=String[],put=String[])
DEF = DataFrame(a=Int64[],fruit=String[],lunch=String[],b=Int64[],c=Int64[],d=Float64[],breakfast=String[])
XYZ = DataFrame(Best=String[],OK=String[],Yuck=String[],a=Float64[])

for i in inputtext
	data = split(split(i,"=")[2],",")
	if startswith(i,"ABC")
		push!(ABC, [parse(Int64,data[1]),parse(Int64,data[2]),parse(Int64,data[3]),data[4],data[5]])
	elseif startswith(i,"DEF")
		push!(DEF, [parse(Int64,data[1]),data[2],data[3],parse(Int64,data[4]),parse(Int64,data[5]),parse(Float64,data[6]),data[7]])
	elseif startswith(i,"XYZ")
		push!(XYZ, [data[1],data[2],data[3],parse(Float64,data[4])])
	end
end

```

Can someone suggest a more elegant way to do this?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [October 27, 2018, 8:26am UTC](https://discourse.julialang.org/t/help-with-string-mapping-from-input/16752/2 "2018-10-27T08:26:44Z")

</div>

You could define something crude as

```julia
parsefield(T::Type{<:Real}, str::AbstractString) = parse(T, str)
parsefield(::Type{T}, str::T) where T <: AbstractString = str
parsefield(::Type{T}, str::AbstractString) where T <: AbstractString = T(str)

schemas = Dict(["ABC" => (a = Int64, b = Int64, c = Int64, animal = String, put = String)])

function parsewithschema(row, schemas)
    key, fields = split(row, '=')
    schema = schemas[key]
    NamedTuple{keys(schema)}(map(parsefield, schemas[key], split(fields, ',')))
end

```

then

```julia
julia> parsewithschema(inputtext[1], schemas)
(a = 1, b = 2, c = 3, animal = "cats", put = "dogs")

```

Would need a bit of refinement, whitespace stripping, and validation for real-life applications, but you get the idea. You can then interface into [Tables.jl](https://github.com/JuliaData/Tables.jl).

Alternatively, leverage the row-reading functionality from one of the CSV reading libraries.

**EDIT** : Try using Parsers.jl for the fields, as described [here](https://discourse.julialang.org/t/fastest-way-to-parse-a-string-of-numbers/16720/4).
