Help with array of arrays and accessing by name

Welcome Forums General PowerShell Q&A Help with array of arrays and accessing by name

Viewing 13 reply threads
  • Author
    Posts
    • #235003
      Participant
      Topics: 1
      Replies: 8
      Points: 28
      Rank: Member

      Brand new to powershell scripting and having some trouble accomplishing what I would like.  Never coded with this before.

      gist – https://gist.github.com/morpolspc/1ea3c43715d693e0addc3cf0bec86337#file-gistfile1-txt

      This does what I want, but not as nicely I would like.  Script searches all files in path, minus excludes, for a regex pattern.  I want to output the found matches/groups in a specific format without duplicates.

      $resultArray += $_.Groups[1].Value + ' ' + $_.Groups[2].Value is the part that bothers me.  My original intention was to create an array of arrays that I could access by name.  In my loop I could then check if the found name/type exists and if not add.  Afterwards it would be easy to create my formatted output by looping through the result array.  I could not for the life of me create an array of arrays accessible by name.

      What I am searching for is icon usage in my project to create a list of all icons and their types used.  Icons are in the format fa-some-icon and each can have types fab, fad, fal, far, fas .  An example usage in my project would be something similar to "fab fa-facebook-f fa-6x mb-20" .  My goal is to create an output file of only the icons I use which can be used as a configuration file.

      • This topic was modified 3 weeks, 6 days ago by scubasteve.
    • #235018
      Participant
      Topics: 5
      Replies: 2373
      Points: 6,011
      Helping Hand
      Rank: Community MVP

      Steve, welcome to Powershell.org. Please take a moment and read the very first post on top of the list of this forum: Read Me Before Posting! You’ll be Glad You Did!.

      When you post code, error messages, sample data or console output format it as code, please.
      In the “Text” view you can use the code tags “PRE“, in the “Visual” view you can use the format template “Preformatted“. You can go back edit your post and fix the formatting – you don’t have to create a new one.
      Thanks in advance.

      If it’s Powershell code you should share it directly instead with a Github Gist.

      Your code looks quite confusing to me. I’d recommend to start small and add additional steps if the small portions work as expected. If you like we can try to develop your code step by step. 😉

      My first question would be: What kind of files are you after? (file format, maybe common name pattern?) Do you want to exclude files or directories and why? Would it be possible to specify the file precisely enough that you don’t need to exclude some?

      Then something like this would be all you need for that step:

      $Path = @(
          'C:\Users\Support\Downloads\test\test'
      )
      $FileList =
      Get-ChildItem -Path $Path -Recurse -File -Filter *.ps1 
    • #235030
      Participant
      Topics: 1
      Replies: 8
      Points: 28
      Rank: Member

      What was provided works perfectly fine, but is not as clean as I would like.  The part I referenced is what I am not happy about.  I would prefer to create an array of arrays accessible by name in this step rather than how I am current doing it.  Something like $resultArray.iconname.typename and create those as I go through my loop while also checking if they already exist so I do not add them multiple times.

      No, I cannot narrow this down to a particular file type.  Yes, I wish to keep the exclude option.  I am searching through a project folder (website) and file types can vary, but want the option to exclude.  Neither of those are an issue or what I am asking help for.

      • This reply was modified 3 weeks, 6 days ago by scubasteve.
    • #235033
      Participant
      Topics: 5
      Replies: 2373
      Points: 6,011
      Helping Hand
      Rank: Community MVP

      I would prefer to create an array of arrays accessible by name. Something like $resultArray.iconname.typename and create those as I go through my loop while also checking if they already exist so I do not need to add them.

      Sounds like you’re used to program in other languages. Powershell might do things differently than you’re used to. In Powershell everything is an object and has properties. I’d expect to be able to make it cleaner if I’d just know what exactly you want to do. Until now your code is hard to understand for me.

    • #235039
      Participant
      Topics: 1
      Replies: 8
      Points: 28
      Rank: Member

      Yes, other languages – never coded with powershell before.  Basically I am wondering if its possible to create an array as follows :

      array

          icon name

              type name

          ...

      and be able to check if they exist (by name) and add them if not.

      • This reply was modified 3 weeks, 6 days ago by scubasteve.
    • #235048
      Participant
      Topics: 1
      Replies: 8
      Points: 28
      Rank: Member

      Maybe this would be better to understand.  Let’s say I have names of people and types of cars they own.  I want to create an array from those where there are no duplicates.

      array.Steve.audi

      array.Steve.ford

      array.John.chevy

      array.Sara.bmw

      ...

      In my code I grouped my regex so all the matches I find can be broken down into two groups – people and cars.  As matches are found I want to create an array from those groups in the format above.  Check if the name exists in the array, and if not, add it.  Check if the name.car exists and if not add it… and so on for all the matches I find.  The result is an array of names and the cars they own… with no duplicates.

      • This reply was modified 3 weeks, 6 days ago by scubasteve.
    • #235054
      Participant
      Topics: 5
      Replies: 2373
      Points: 6,011
      Helping Hand
      Rank: Community MVP

      Could you share some (sanitized) sample data to play with?

    • #235063
      Participant
      Topics: 1
      Replies: 8
      Points: 28
      Rank: Member

      Could you share some (sanitized) sample data to play with?

      https://gist.github.com/morpolspc/3ffd4ff65a311c053e18a354e9240e0d#file-gistfile1-txt

      Here ya’ go.  Only two icons in here with different variations of each and some duplicates which covers a real life scenario.  In my actual use there could be thousands of matches found and narrowed down to a small subset when duplicates are removed.

    • #235180
      Participant
      Topics: 1
      Replies: 8
      Points: 28
      Rank: Member

      I ‘think’ I just found a method to use which is similar to what I originally intended.  Will have time to try it out later and will report back here if I do in case it is useful to anyone else.

    • #235183
      Participant
      Topics: 5
      Replies: 2373
      Points: 6,011
      Helping Hand
      Rank: Community MVP

      I’m still pretty unsure if I got it right. 😉 So I took your sample data file and played a little …

      $inputFile =
      'D:\sample\gistfile1.txt'
      
      $lookupTable = 
      @{
          fab = "brands"
          fad = "duotone"
          fal = "light"
          far = "regular"
          fas = "solid"
      }
      $pattern = '(fa[lrsdb]{1}) fa-([a-z-]+)'
      
      $report = 
      Select-String -Path $inputFile -Pattern $pattern -AllMatches | 
      Select-Object -ExpandProperty Matches |
      ForEach-Object {
          [PSCustomObject]@{
              type1     = $_.Groups[1].Value
              type2     = $_.Groups[2].Value
              type1Name = $lookupTable[$_.Groups[1].Value]
          }
      }
      

      The output would be this:

      $report
      
      type1 type2    type1Name
      ----- -----    ---------
      fas   user     solid
      fas   user     solid
      fas   user     solid
      fab   file-alt brands
      fal   user     light
      far   user     regular
      far   file-alt regular
      far   file-alt regular
      fal   file-alt light
      

      But because you have a variable with the results and you can play with it. For example group it like you want:

      $report | 
      Group-Object -Property type1Name
      

      Does this lead to something you want?

    • #235219
      Participant
      Topics: 1
      Replies: 8
      Points: 28
      Rank: Member

      I got it figured out and working great.  https://gist.github.com/morpolspc/482495d9fd72c996b273ed0ec689ce2d

      Will create a file such as :

      version: 5.13.0
      icons:
        - arrow-circle-right:
            - solid
        - ban:
            - solid
        - bars:
            - regular
        - facebook-f:
            - brands
        - lock-alt:
            - solid
        - search:
            - solid
        - user:
            - duotone
            - light
            - solid
        - user-circle:
            - solid
        - user-clock:
            - duotone

      The way the result is formatted is required by the app I would load this file in – its a configuration file for it and needs to be this format to load properly.  In actual use there would be way more results than this.

      I noticed your lookup table as well and implemented that.  I use those all the time so not sure why I put a case statement in there to begin with.  I appreciate you taking the time to look, respond, and help out.  It was a little rough not being familiar with powershell at all, but I do feel a little more comfortable with it now – things are just a little different than what I am used to.

    • #235234
      Participant
      Topics: 1
      Replies: 8
      Points: 28
      Rank: Member

      I spoke too soon 🙁

      Just tested this in a real project and I am getting a mystery whitespace in my output :

      version: 5.13.0
      icons:
        - angle-left:
             - solid
         - angle-right:
             - solid
         - apple:
             - brands
         - arrow-circle-right:
             - regular
             - solid

      There should be two whitespaces before the icon name and six before its types.  I clearly have 2 and 6 spaces in my code so not sure where these extra spaces are coming from.  Strangely the first icon name has the correct 2 spaces before it… everything else after that is one additional.

      I double checked the values and even went as far as adding .trim() to all of them, but no change so I’m pretty sure the actual values are correct.  Somewhere here is where I think the problem is happening :

      #sort by Name and sort Values of each
      $output = foreach($icon in $table.GetEnumerator() | sort -Property Name) {
          "  - " + $icon.Name + ":rn"
          foreach($type in $icon.Value | sort) {
              "      - " + $fa_types[$type] + "rn"
          }
      }

      Anyone see anything I’m not?

      • This reply was modified 3 weeks, 6 days ago by scubasteve.
      • This reply was modified 3 weeks, 6 days ago by scubasteve.
    • #235264
      Participant
      Topics: 5
      Replies: 2373
      Points: 6,011
      Helping Hand
      Rank: Community MVP

      …. things are just a little different than what I am used to.

      That’s what I meant. 😉 Powershell was not meant to be for programmers originally.

      Anyone see anything I’m not?

      I’d recommend using the format operator. Here’s an example:

      $var1 = 'angle-left'
      $var2 = 'solid'
      $var3 = 'apple'
      $var4 = 'brands'
      
      
      $Template = @"
      version: 5.13.0
      icons:
        - {0}:
            - {1}
        - {2}:
            - {3}
      "@
      
      $Template -f $var1, $var2, $var3, $var4
      

      This way it’s easier to maintain a certain format I think.

      Here you can get some more info about it:
      https://social.technet.microsoft.com/wiki/contents/articles/7855.powershell-using-the-f-format-operator.aspx
      https://ss64.com/ps/syntax-f-operator.html
      https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-7#format-operator–f

    • #235390
      Participant
      Topics: 1
      Replies: 8
      Points: 28
      Rank: Member

      Figured out with the help of stackoverflow on this one.

      foreach($icon in $table.GetEnumerator() | sort -Property Name) {
          $output += " - " + $icon.Name + ":rn"
          foreach($type in $icon.Value | sort) {
              $output += " - " + $fa_types[$type] + "rn"
          }
      }

      The reason this was happening originally is because I was ‘printing an array in a string’ and it ‘writes it as item of an array to the $output’.  I should have caught this one earlier.

      I believe your format suggestion would work as well Olaf, but there is a possibility of over 10,000 icons meaning over 10,000 lines in the output.  I just ran this on one of my smaller projects and still had over 200 lines in my output.

Viewing 13 reply threads
  • You must be logged in to reply to this topic.