将对象数组合并为单个对象数组

时间:2017-10-05 13:59:30

标签: javascript arrays lodash ramda.js

我正在寻找对象的合并数组到单个对象数组中,并将对象的键附加到来自内部对象键的每个键

我有像

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

并且键和对象的长度未知,我想将其合并为

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

我尝试过使用Ramda mergeAll,但它不适用于我的情况,因为它只合并对象

这是我试过的东西

 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)

我正在尝试将每个修改过的对象添加到mergerArray数组,但它为每次迭代添加,最后,它创建了2个数组

mergedArray仍在创建两个不同的数组,其中对象的键要附加到对象的属性中,但我希望它在对象的单个数组中合并。

我错过了什么。我该怎么做才能解决这个问题?

建议一些帮助。

4 个答案:

答案 0 :(得分:1)

使用Array.prototype.map和index作为第二个参数传递给它的回调来从Account对象中获取元素

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));

答案 1 :(得分:1)

在普通的Javascript中,您可以迭代给定对象的键并迭代数组,并使用新键从内部属性中构建一个新对象。



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; }




答案 2 :(得分:1)

嗯,它不漂亮,但你可以这样做:

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

您可以在 Ramda REPL 上看到这一点。

答案 3 :(得分:1)

在这里,另一种选择。我从ramda食谱列表中提取了一个renameBy函数。如果需要,您可以将所有内容组合到一行。

// 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)