2

I have a list of Persona models being returned in p.followings and I want to extract the followed_id field from this list of models into a separate list.

p.followings

returns...

[
  %Poaster.Personas.Following{
    __meta__: #Ecto.Schema.Metadata<:loaded, "followings">,
    followed: %Poaster.Personas.Persona{
      __meta__: #Ecto.Schema.Metadata<:loaded, "personas">,
      background_image_url: nil,
      bio: "ASDF",
      followings: #Ecto.Association.NotLoaded<association :followings is not loaded>,
      id: 42,
      inserted_at: ~N[2020-08-14 01:52:17],
      name: nil,
      profile_image_url: nil,
      updated_at: ~N[2020-08-14 16:19:56],
      user: #Ecto.Association.NotLoaded<association :user is not loaded>,
      user_id: 1,
      username: "test"
    },
    followed_id: 42,
    id: 1,
    inserted_at: ~N[2020-08-12 20:35:09],
    persona: #Ecto.Association.NotLoaded<association :persona is not loaded>,
    persona_id: 1,
    updated_at: ~N[2020-08-12 20:35:09]
  }
]

I simply want to get a list of the followed_id here so I can make a query to get a list of posts from those personas I am following.

I want to get back something like [42].

When I do Enum.map(ps.followings, fn follow -> follow.followed_id end), which is what I expected to be able to run to get this, I am getting back in the console just '*'

When I tried to use a comprehension with the into option, into an empty list, this is also what I got.

persona_ids = []
for p <- p.followings, into: persona_ids, do: p.followed_id
IO.inspect(persona_ids)
[]

However, when I run the above comprehension with p.followed, it returns a list of the Personas:

for p <- p.followings, into: persona_ids, do: p.followed   
[
  %Poaster.Personas.Persona{
    __meta__: #Ecto.Schema.Metadata<:loaded, "personas">,
    background_image_url: nil,
    bio: "ASDF",
    followings: #Ecto.Association.NotLoaded<association :followings is not loaded>,
    id: 42,
    inserted_at: ~N[2020-08-14 01:52:17],
    name: nil,
    profile_image_url: nil,
    updated_at: ~N[2020-08-14 16:19:56],
    user: #Ecto.Association.NotLoaded<association :user is not loaded>,
    user_id: 1,
    username: "test"
  }
]

I need the list of IDs, not the list of Persona models, so that I can make an appropriate Ecto query to get the posts from the Personas I follow.

What is going on here? What am I doing wrong? Is there a better way to do what I am trying to do?

  • 2
    `'*'` is actually equivalent to `[42]`, because 42 is the codepoint for `*` and when you create a list in Elixir with integers that are all codepoints for characters, you get the charlist printed when you try to print it, but you should be able to use the list normally. Try doing `List.first` on that result and you'll see it produces 42. – sbacarob Aug 18 '20 at 17:45
  • 1
    https://stackoverflow.com/questions/30037914/elixir-lists-interpreted-as-char-lists you might find an answer here – sbacarob Aug 18 '20 at 17:46
  • Well.....that does answer some questions. Thanks, @sbacarob! – FullMetalEngineer Aug 18 '20 at 17:51
  • If you answer this in a post, I'll mark it as accepted – FullMetalEngineer Aug 18 '20 at 18:52
  • 2
    Also note that using the `into:` in the comprehension will not affect the previously declared `persona_ids` variable, since all variables are immutable in Elixir. – potibas Aug 18 '20 at 20:54

1 Answers1

3

As I mentioned in the comment, and as discussed on this other post, the '*' you're receiving is in fact the list you expect: [42].

This happens because 42 is the codepoint of the * character (you can verify this by doing ?* in an iex session). In Elixir and Erlang, when you have a list of integers and all of the integers are valid codepoints for characters, it will print the charlist when you use IO.inspect, but it is a list and you can use it like you would use any list.

For instance, if you type [104, 101, 108, 108, 111] into the iex prompt, you will get back 'hello', but the single quotes denote that it's a charlist, and you can perform any list operations you'd like on it.

sbacarob
  • 2,092
  • 1
  • 14
  • 19
  • Totally makes sense once you mentioned it mapped to that string character, that was just a very unexpected behavior for me so it never even crossed my mind. I appreciate your help! – FullMetalEngineer Aug 18 '20 at 20:59