Map add / reduce two array objects with one index

I have two array objects:

var arr1 = [
    {
        name: 1,
        value: 10
    },
    {
        name: 2,
        value: 15
    }
]

var arr2 = [
    {
        name: 3,
        value: 5
    },
    {
        name: 4,
        value: 3
    }
]

I want to override the key and reduce each file with the same index.

output:

var arr1 = [
    {
        itemLabel: 1,
        itemValue: 5
    }, 
    {
        itemLabel: 2,
        itemValue: 12
    }
]

Now I do the following:

formatData = arr1.map((row, index) => ({
    itemLabel: arr1.name,
    itemValue: arr1.value - arr2[index].value
}))

Is there a better solution for this?

+4
source share
4 answers

Single man army

A simple recursive program that processes everything in one function. There is a clear mixture of problems that degrades the overall readability of the function. We will see one of these tools for this problem below.

const main = ([x, ...xs], [y, ...ys]) =>
  x === undefined || y === undefined
    ? []
    : [ { itemLabel: x.name, itemValue: x.value - y.value } ] .concat (main (xs, ys))

const arr1 =
  [ { name: 1, value: 10 }, { name: 2, value: 15 } ]

const arr2 =
  [ { name: 3, value: 5 }, { name: 4, value: 3 } ]
  
console.log (main (arr1, arr2))
// [ { itemLabel: 1, itemValue: 5 },
//   { itemLabel: 2, itemValue: 12 } ]
Run codeHide result

Thinking with types

This part of the answer is influenced by type theory from the category of monoids - I will not go too far, because I think that the code should be able to demonstrate itself.

, : Foo Bar

  • Foo - name value
  • Bar - itemLabel itemValue

"", , ,

const Foo = (name, value) =>
  ({ name
   , value
   })

const Bar = (itemLabel, itemValue) =>
  ({ itemLabel
   , itemValue
   })

,

const arr1 =
  [ Foo (1, 10), Foo (2, 15) ]

const arr2 =
  [ Foo (3, 5), Foo (4, 3) ]

,

console.log (arr1)
// [ { name: 1, value: 10 },
//   { name: 2, value: 15 } ]

console.log (arr2)
// [ { name: 3, value: 5 },
//   { name: 4, value: 3 } ]

. Foo. - , Foo , ( ),

const zip = ([ x, ...xs ], [ y, ...ys ]) =>
  x === undefined || y === undefined
    ? []
    : [ [ x, y ] ] .concat (zip (xs, ys))

console.log (zip (arr1, arr2))
// [ [ { name: 1, value: 10 },
//     { name: 3, value: 5 } ],
//   [ { name: 2, value: 15 },
//     { name: 4, value: 3 } ] ]

: concat

Foo , , . concat, Foo

// generic concat
const concat = (m1, m2) =>
  m1.concat (m2)

const Foo = (name, value) =>
  ({ name
   , value
   , concat: ({name:_, value:value2}) =>
       // keep the name from the first, subtract value2 from value
       Foo (name, value - value2)
   })

console.log (concat (Foo (1, 10), Foo (3, 5)))
// { name: 1, value: 5, concat: [Function] }

concat? Array String Monoid!

concat ([ 1, 2 ], [ 3, 4 ])
// [ 1, 2, 3, 4 ]

concat ('foo', 'bar')
// 'foobar'

, Foo. name Foo , value . "" . , .

const apply = f => xs =>
  f (...xs)

zip (arr1, arr2) .map (apply (concat))
// [ { name: 1, value: 5, concat: [Function] },
//   { name: 2, value: 12, concat: [Function] } ]

, Foo name value, , Bar. - - ,

Bar.fromFoo = ({ name, value }) =>
  Bar (name, value)

Bar.fromFoo (Foo (1,2))
// { itemLabel: 1, itemValue: 2 }

zip (arr1, arr2)
  .map (apply (concat))
  .map (Bar.fromFoo)
// [ { itemLabel: 1, itemValue: 5 },
//   { itemLabel: 2, itemValue: 12 } ]

, . ; .

// main :: ([Foo], [Foo]) -> [Bar]
const main = (xs, ys) =>
  zip (xs, ys)
    .map (apply (concat))
    .map (Bar.fromFoo)

- ,

const Foo = (name, value) =>
  ({ name
   , value
   , concat: ({name:_, value:value2}) =>
       Foo (name, value - value2)
   })
  
const Bar = (itemLabel, itemValue) =>
  ({ itemLabel
   , itemValue
   })

Bar.fromFoo = ({ name, value }) =>
  Bar (name, value)

const concat = (m1, m2) =>
  m1.concat (m2)
  
const apply = f => xs =>
  f (...xs)  

const zip = ([ x, ...xs ], [ y, ...ys ]) =>
  x === undefined || y === undefined
    ? []
    : [ [ x, y ] ] .concat (zip (xs, ys))

const main = (xs, ys) =>
  zip (xs, ys)
    .map (apply (concat))
    .map (Bar.fromFoo)

const arr1 =
  [ Foo (1, 10), Foo (2, 15) ]
  
const arr2 =
  [ Foo (3, 5), Foo (4, 3) ]

console.log (main (arr1, arr2))
// [ { itemLabel: 1, itemValue: 5 },
//   { itemLabel: 2, itemValue: 12 } ]
Hide result

.map - .map, . [[x1,y1], [x2,y2], ...] zip. , , m.map(f).map(g) m.map(compose(f,g)) . , , , , , -.

+1

, :

var arr1 =[{
  name: 1,
  value: 10 
}, {
  name: 2,
  value: 15
}];

var arr2= [{
  name: 3,
  value: 5 
}, {
  name: 4,
  value: 3
}]


const createObject=(arr1,arr2,ret=[])=>{
  if(arr1.length!==arr2.length){
    throw("Arrays should be the same length.")
  }
  const item = {
    itemLabel: arr1[0].name,
    itemValue: arr1[0].value - arr2[0].value
  };
  if(arr1.length===0){
    return ret;
  };
  return createObject(arr1.slice(1),arr2.slice(1),ret.concat(item));
}
console.log(createObject(arr1,arr2));
Hide result

, map reduce, arr1, arr2 ( ), , . :

var arr1 =[{
  name: 1,
  value: 10 
}, {
  name: 2,
  value: 15
}];

var arr2= [{
  name: 3,
  value: 5 
}, {
  name: 4,
  value: 3
}];


const mapFunction = arr2 => (item,index) => {
  return {
    itemLabel: item.name,
    itemValue: item.value - arr2[index].value
  }
}

var createObject=(arr1,arr2,ret=[])=>{
  if(arr1.length!==arr2.length){
    throw("Arrays should be the same length.")
  }
  const mf = mapFunction(arr2);
  return arr1.map(mf);
}
console.log(createObject(arr1,arr2));
Hide result

CodingIntrigue : "", .

+1

, () .

- ,

arr1 arr2. , . .

, , , .

,

const mapWithObject = (obj2, obj1, index) => ({
    itemLabel: obj1.name,
    itemValue: obj1.value - obj2[index].value
})

// example call
const result = mapWithObject(arr2, arr1[0], 0)

, map, 3 2.

Curry it

const mapWithObject = obj2 => (obj1, index) => ({
  itemLabel: obj1.name,
  itemValue: obj1.value - obj2[index].value
})

const mapObject_with_arr2 = mapWithObject(arr2)

// example call
const result = mapObject_with_arr2(arr1[0], 0)

const arr1 = [{
    name: 1,
    value: 10
  },
  {
    name: 2,
    value: 15
  }
]

const arr2 = [{
    name: 3,
    value: 5
  },
  {
    name: 4,
    value: 3
  }
]

const mapWithObject = obj2 => (obj1, index) => ({
  itemLabel: obj1.name,
  itemValue: obj1.value - obj2[index].value
})

const mapObject_with_arr2 = mapWithObject(arr2)

const mappedObject = arr1.map(mapObject_with_arr2)

console.log(mappedObject)
Hide result
+1

, , :

  • , "" arr1 arr2

    [a, b, c] + [1, 2, 3] -> [ [ a, 1 ], [ b, 2 ], [ c, 3 ] ]
    
  • ,

    { a: 1, b: 10 } + { a: 2, b: 20 } -> { a: 1, b: -10 } 
    
  • , , .

:

var arr1=[{name:1,value:10},{name:2,value:15}],arr2=[{name:3,value:5},{name:4,value:3}];

// This is a very general method that bundles two
// arrays in an array of pairs. Put it in your utils
// and you can use it everywhere
const pairs = (arr1, arr2) => Array.from(
  { length: Math.max(arr1.length, arr2.length) },
  (_, i) => [ arr1[i], arr2[i] ]
);

// This defines our merge strategy for two objects.
// Ideally, you should give it a better name, based
// on what the objects represent
const merge = 
  (base, ext) => ({ 
    itemLabel: base.name,
    itemValue: base.value - ext.value
  });

// This is a helper that "applies" our merge method 
// to an array of two items.
const mergePair = ([ base, ext ]) => merge(base, ext);

// Another helper that composes `pairs` and `mergePair` 
// to allow you to pass your original data.
const mergeArrays = (arr1, arr2) => pairs(arr1, arr2).map(mergePair);

console.log(mergeArrays(arr1, arr2));
Hide result
0

Source: https://habr.com/ru/post/1691778/


All Articles