0

I am looking for merge arrays of object into single array of object and append key of object to each key from inner object's key

I have object like

    var myObj = {
                "Details": [{
                        "car": "Audi",
                        "price": 40000,
                        "color": "blue"
                    },
                    {
                        "car": "BMW",
                        "price": 35000,
                        "color": "black"
                    }
                ],
                "Accounts": [{
                        "Total": 2000
                    },
                    {
                        "Total": 3000
                    }
                ]
            }

and Keys and objects length is not known, I want to merge it like

[
          {
            "Detailscar": "Audi",
            "Detailsprice": 40000,
            "Detailscolor": "blue",
            "AccountsTotal": 2000
          },
          {
            "Detailscar": "BMW",
            "Detailsprice": 35000,
            "Detailscolor": "black",
            "AccountsTotal": 3000
          }
        ]

I have tried with Ramda mergeAll but it is not working in my case as it only merge objects

here is what I tried

 var mergedArray = []
        R.mapObjIndexed((instance, instanceName) => {
            mergedArray.push(R.map((innerObj) => {
                var customObject = {};
                R.forEach((key) => {
                    customObject[`${instanceName}${key}`] = innerObj[key]
                }, Object.keys(innerObj))
                return customObject;
            }, instance))
        }, myObj)

I am trying add to each modified object to the mergerArray array but it adding for each iteration and finally, it is creating 2 arrays

mergedArray is still creating two different arrays with the key of the object to be appended to the properties of the object but I want it to be merged in the single array of object.

I am missing something. What should I do to resolve this issue?

Suggest some help.

1
  • @Sam I have taken back the vote but I'm not the only one who voted. So your question might get closed. This is why it is important to share effort. Commented Oct 5, 2017 at 14:34

4 Answers 4

1

Use Array.prototype.map and index as second parameter passsed to its callback to get element from Account object

const data = {
  "Details": [
    {
      "car": "Audi",
      "price": 40000,
      "color": "blue"
    },
    {
      "car": "BMW",
      "price": 35000,
      "color": "black"
    },
    {
      "car": "Porsche",
      "price": 60000,
      "color": "green"
    }

  ],
  "Accounts": [
    {
      "Total": 2000
    },
    {
      "Total": 3000
    },
    {
      "Total": 3000
    }

  ]
};

const mergeCarData = ({ Details, Accounts} = {}) => {
  return Details.length === Accounts.length ? Details.map(({ car, price, color}, idx) => ({
    Detailscar: car,
    Detailsprice: price,
    Detailscolor: color,
    AccountsTotal: Accounts[idx].Total
  })) : [];
};

console.log(mergeCarData(data));

Sign up to request clarification or add additional context in comments.

Comments

1

In plain Javascript, you could iterate the keys of the given object and iterate the arrays and build a new object out of the inner properties with a new key.

var object = { Details: [{ car: "Audi", price: 40000, color: "blue" }, { car: "BMW", price: 35000, color: "black" }], Accounts: [{ Total: 2000 }, { Total: 3000 }] },
    result = Object.keys(object).reduce(function (returnValue, parentKey) {
        object[parentKey].forEach(function (currentObj, i) {
            returnValue[i] = returnValue[i] || {};
            Object.keys(currentObj).forEach(function (childKey) {
                returnValue[i][parentKey + childKey] = currentObj[childKey];
            });
        });
        return returnValue;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

1 Comment

I just updated variable names so that it becomes easier to read. If you think its not required, please revert it. :-)
1

Well, it's not pretty, but you could do something like this:

const convert = pipe(
  mapObjIndexed((val, name) => pipe(
    map(toPairs),
    map(map(([prop, propVal]) => objOf(name + prop, propVal))),
    map(mergeAll),
  )(val)),
  values,
  apply(zipWith(merge))
)

You can see this in action on the Ramda REPL.

Comments

1

Here you go, another option. I pulled a renameBy function from ramda recipe list. You can combine all the stuff on to one line if you want.

// https://github.com/ramda/ramda/wiki/Cookbook#rename-keys-of-an-object
const renameBy = R.curry((fn, obj) => R.pipe(R.toPairs, R.map(R.adjust(fn, 0)), R.fromPairs)(obj));

let convertNames = R.mapObjIndexed((value, key)=> {
    return R.map(renameBy(R.concat(key)), value)
})

let mergeUp = R.pipe(R.values, R.reduce(R.mergeDeepLeft,[]), R.values)

let convert = R.pipe(convertNames, mergeUp)
convert(myObj)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.