Associative array/Merging: Difference between revisions

From Rosetta Code
Content added Content deleted
(Promoted to full task status.)
m (→‎{{header|REXX}}: used a better idiomatic quotation method, added wording to the REXX section header.)
Line 258: Line 258:


=={{header|REXX}}==
=={{header|REXX}}==
The REXX language has no native support to acquire the keys of an associate array, so it must be performed at definition time.
The REXX language has no native support to acquire the keys of an associate array after they have been defined,  
<br>so it must be performed at definition time.
<lang rexx>/*REXX program merges two associative arrays (requiring an external list of indices). */
<lang rexx>/*REXX program merges two associative arrays (requiring an external list of indices). */
$.= /*define default value(s) for arrays. */
$.= /*define default value(s) for arrays. */
Line 277: Line 278:
show: procedure expose $.; parse arg AAn; say; _= '═'
show: procedure expose $.; parse arg AAn; say; _= '═'
do j=1 for words($.AAn.?keys)
do j=1 for words($.AAn.?keys)
if j==1 then say center('associate array', 21, _) center('key' , 9, _),
if j==1 then say center('associate array', 21, _) center("key" , 9, _),
center('value', 13, _)
center('value', 13, _)
key= word($.AAn.?keys, j); say center(AAn, 21) right(key, 9) $.AAn.key
key= word($.AAn.?keys, j); say center(AAn, 21) right(key, 9) $.AAn.key

Revision as of 15:15, 14 January 2020

Task
Associative array/Merging
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Define two associative arrays, where one represents the following "base" data:

Key Value
"name" "Rocket Skates"
"price" 12.75
"color" "yellow"

And the other represents "update" data:

Key Value
"price" 15.25
"color" "red"
"year" 1974

Merge these into a new associative array that contains every key found in either of the source ones. Each key should map to the value in the second (update) table if that exists, or else to the value in the first (base) table. If possible, do this in a way that does not mutate the original two associative arrays. Obviously this should be done in a way that would work for any data, not just the specific data given here, but in this example the result should be:

Key Value
"name" "Rocket Skates"
"price" 15.25
"color" "red"
"year" 1974

Factor

The assoc-union word does this. assoc-union! is a variant that mutates the first associative array.

Works with: Factor version 0.99 2019-10-06

<lang factor>USING: assocs prettyprint ;

{ { "name" "Rocket Skates" } { "price" 12.75 } { "color" "yellow" } } { { "price" 15.25 } { "color" "red" } { "year" 1974 } } assoc-union .</lang>

Output:
V{
    { "name" "Rocket Skates" }
    { "price" 15.25 }
    { "color" "red" }
    { "year" 1974 }
}

Go

<lang go>package main

import "fmt"

type assoc map[string]interface{}

func merge(base, update assoc) assoc {

   result := make(assoc)
   for k, v := range base {
       result[k] = v
   }
   for k, v := range update {
       result[k] = v
   }
   return result

}

func main() {

   base := assoc{"name": "Rocket Skates", "price": 12.75, "color": "yellow"}
   update := assoc{"price": 15.25, "color": "red", "year": 1974}
   result := merge(base, update)
   fmt.Println(result)

}</lang>

Output:
map[color:red name:Rocket Skates price:15.25 year:1974]

JavaScript

<lang javascript>(() => {

   'use strict';
   console.log(JSON.stringify(
       Object.assign({}, // Fresh dictionary.
           { // Base.
               "name": "Rocket Skates",
               "price": 12.75,
               "color": "yellow"
           }, { // Update.
               "price": 15.25,
               "color": "red",
               "year": 1974
           }
       ), 
       null, 2
   ))

})();</lang>

Output:
{
  "name": "Rocket Skates",
  "price": 15.25,
  "color": "red",
  "year": 1974
}

Julia

julia> dict1 = Dict("name" => "Rocket Skates", "price" => 12.75, "color" => "yellow")
Dict{String,Any} with 3 entries:
  "name"  => "Rocket Skates"
  "price" => 12.75
  "color" => "yellow"

julia> dict2 = Dict("price" => 15.25, "color" => "red", "year" => 1974)
Dict{String,Any} with 3 entries:
  "price" => 15.25
  "year"  => 1974
  "color" => "red"

julia> merge(dict1, dict2)
Dict{String,Any} with 4 entries:
  "name"  => "Rocket Skates"
  "price" => 15.25
  "year"  => 1974
  "color" => "red"

julia> merge(dict2, dict1)
Dict{String,Any} with 4 entries:
  "name"  => "Rocket Skates"
  "price" => 12.75
  "year"  => 1974
  "color" => "yellow"

julia> union(dict1, dict2)
6-element Array{Pair{String,Any},1}:
  "name" => "Rocket Skates"
 "price" => 12.75
 "color" => "yellow"
 "price" => 15.25
  "year" => 1974
 "color" => "red"

Lua

<lang Lua>base = {name="Rocket Skates", price=12.75, color="yellow"} update = {price=15.25, color="red", year=1974}

--clone the base data -- result = {} for key,val in pairs(base) do

   result[key] = val

end

--copy in the update data -- for key,val in pairs(update) do

   result[key] = val

end

--print the result -- for key,val in pairs(result) do

   print(string.format("%s: %s", key, val))

end</lang>

Output:
price: 15.25
color: red
year: 1974
name: Rocket Skates

MiniScript

MiniScript supports merging maps with the + operator. <lang MiniScript>base = {"name":"Rocket Skates", "price":12.75, "color":"yellow"} update = {"price":15.25, "color":"red", "year":1974}

result = base + update

print result</lang>

Output:
{"color": "red", "name": "Rocket Skates", "price": 15.25, "year": 1974}

Perl 6

Works with: Rakudo version 2019.11

I must say I somewhat disagree with the terminology. The requested operation is an update not a merge. Demonstrate both an update and a merge. Associative arrays are commonly called hashes in Perl 6.

<lang perl6># Show original hashes say my %base = :name('Rocket Skates'), :price<12.75>, :color<yellow>; say my %update = :price<15.25>, :color<red>, :year<1974>;

  1. Need to assign to anonymous hash to get the desired results and avoid mutating
  2. TIMTOWTDI

say "\nUpdate:\n", join "\n", sort %=%base, %update;

  1. Same

say "\nUpdate:\n", {%base, %update}.sort.join: "\n";

say "\nMerge:\n", join "\n", sort ((%=%base).push: %update)».join: ', ';

  1. Same

say "\nMerge:\n", ({%base}.push: %update)».join(', ').sort.join: "\n";

  1. Demonstrate unmutated hashes

say "\n", %base, "\n", %update;</lang>

Output:
{color => yellow, name => Rocket Skates, price => 12.75}
{color => red, price => 15.25, year => 1974}

Update:
color	red
name	Rocket Skates
price	15.25
year	1974

Update:
color	red
name	Rocket Skates
price	15.25
year	1974

Merge:
color	yellow, red
name	Rocket Skates
price	12.75, 15.25
year	1974

Merge:
color	yellow, red
name	Rocket Skates
price	12.75, 15.25
year	1974

{color => yellow, name => Rocket Skates, price => 12.75}
{color => red, price => 15.25, year => 1974}

Python

As of Python 3.5, this can be solved with the dictionary unpacking operator. <lang Python>base = {"name":"Rocket Skates", "price":12.75, "color":"yellow"} update = {"price":15.25, "color":"red", "year":1974}

result = {**base, **update}

print(result)</lang>

Output:
{'name': 'Rocket Skates', 'price': 15.25, 'color': 'red', 'year': 1974}

REXX

The REXX language has no native support to acquire the keys of an associate array after they have been defined,  
so it must be performed at definition time. <lang rexx>/*REXX program merges two associative arrays (requiring an external list of indices). */ $.= /*define default value(s) for arrays. */ call defAA 'base', "name Rocket Skates", 'price 12.75', "color yellow" call defAA 'update', "price 15.25", "color red", 'year 1974' call show 'base' call show 'update' call show 'new' exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ defAA: procedure expose $.; parse arg AAn; new= 'new'

        do j=2  to arg();   parse value arg(j)  with  key val
        $.AAn.key=val;  if wordpos(key, $.AAN.?keys)==0  then $.AAn.?keys=$.AAn.?keys key
        $.new.key=val;  if wordpos(key, $.new.?keys)==0  then $.new.?keys=$.new.?keys key
        end   /*j*/
      return

/*──────────────────────────────────────────────────────────────────────────────────────*/ show: procedure expose $.; parse arg AAn; say; _= '═'

        do j=1  for words($.AAn.?keys)
        if j==1  then say center('associate array', 21, _)  center("key" ,   9, _),
                                                            center('value', 13, _)
        key= word($.AAn.?keys, j);   say  center(AAn, 21)  right(key, 9)  $.AAn.key
        end   /*j*/
      return</lang>
output   when using the internal default inputs:
═══associate array═══ ═══key═══ ════value════
        base               name Rocket Skates
        base              price 12.75
        base              color yellow

═══associate array═══ ═══key═══ ════value════
       update             price 15.25
       update             color red
       update              year 1974

═══associate array═══ ═══key═══ ════value════
         new               name Rocket Skates
         new              price 15.25
         new              color red
         new               year 1974

zkl

<lang zkl>base:=Dictionary(

  "name", 	"Rocket Skates",
  "price", 	12.75,
  "color", 	"yellow",);

update:=Dictionary(

  "price", 	15.25,
  "color", 	"red",
  "year", 	1974,);

update.pump( new:=base.copy() );

new.pump(Void,fcn([(k,v)]){ println("%s\t%s".fmt(k,v)) });</lang>

Output:
price	15.25
color	red
year	1974
name	Rocket Skates