挑选和合并JavaScript数组

时间:2015-06-22 00:21:44

标签: javascript node.js mongodb lodash

我有一个如下所示的数据集:

[
    {
        ProductID: 1,
        ProductName: 'MyProduct',
        Description: '.. some text here ..',
        UnwantedData: 'garbage here'
    },
    {
        ProductID: 2,
        ProductName: 'MyOtherProduct',
        Description: '.. some text here ..',
        UnwantedData: 'garbage herAe',
        GarbageField: '.. lorem ipsum ..'
    }
]

我还有一个如下所示的参考数组:

[
    {
        name: 'ProductId',
        map_to: 'item_id',
    },
    {
        name: 'ProductName',
        map_to: 'item_name',
    },
    {
        name: 'Description',
        map_to: 'description',
    },
]

我想要做的是使用该引用数组基本上删除“不需要的”数据(即参考数组中不是name s的属性)并将键替换为它应该的任何内容被映射到(即ProductId->item_id)。

生成的数组应如下所示:

[
    {
        item_id: 1,
        item_name: 'MyProduct',
        description: '.. some text here ..'
    },
    {
        item_id: 2,
        item_name: 'MyOtherProduct',
        description: '.. some text here ..'
    }
]

到目前为止我做了什么

鉴于ref是参考数组,data是产品列表。

var only = _.map( ref, 'name' );
var products = [];

async.eachLimit( data, 20, function(item, cb) {

    products.push( _.pick(item, only) );
    cb();
}, function(err) {

    // .. then I iterate over the products array and manually replace each property 
    // I haven't done this yet
});

这段代码应该可以工作,但感觉有点低效,我想知道是否有更好的方法来实现所需的结果数组,因为我将把它们存储在MongoDB中。

有人能在这里说清楚吗?

3 个答案:

答案 0 :(得分:2)

您可以尝试for循环:

var result = [];
for(var i=0; i<data.length; ++i) {
  result[i] = {};
  for(var j=0; j<ref.length; ++j)
    result[i][ref[j].map_to] = data[i][ref[j].name];   
}

&#13;
&#13;
var data = [
  {
    ProductID: 1,
    ProductName: 'MyProduct',
    Description: '.. some text here ..',
    UnwantedData: 'garbage here'
  }, {
    ProductID: 2,
    ProductName: 'MyOtherProduct',
    Description: '.. some text here ..',
    UnwantedData: 'garbage herAe',
    GarbageField: '.. lorem ipsum ..'
  }
];
var ref = [
  {
    name: 'ProductID',
    map_to: 'item_id',
  }, {
    name: 'ProductName',
    map_to: 'item_name',
  }, {
    name: 'Description',
    map_to: 'description',
  },
];
var result = [];
for(var i=0; i<data.length; ++i) {
  result[i] = {};
  for(var j=0; j<ref.length; ++j)
    result[i][ref[j].map_to] = data[i][ref[j].name];   
}
console.log(result);
&#13;
&#13;
&#13;

或者,使用ES5数组方法,

data.map(function(old) {
  return ref.reduce(function(obj, assoc) {
    obj[assoc.map_to] = old[assoc.name];
    return obj;
  }, {});
});

&#13;
&#13;
var data = [
  {
    ProductID: 1,
    ProductName: 'MyProduct',
    Description: '.. some text here ..',
    UnwantedData: 'garbage here'
  }, {
    ProductID: 2,
    ProductName: 'MyOtherProduct',
    Description: '.. some text here ..',
    UnwantedData: 'garbage herAe',
    GarbageField: '.. lorem ipsum ..'
  }
];
var ref = [
  {
    name: 'ProductID',
    map_to: 'item_id',
  }, {
    name: 'ProductName',
    map_to: 'item_name',
  }, {
    name: 'Description',
    map_to: 'description',
  },
];
console.log(data.map(function(old) {
  return ref.reduce(function(obj, assoc) {
    obj[assoc.map_to] = old[assoc.name];
    return obj;
  }, {});
}));
&#13;
&#13;
&#13;

答案 1 :(得分:2)

我通常发现使用_.pairs将对象拆分成对更容易,对对子进行操作,然后将它们转回_.object对象:

function goodPair(product_pair) {
    var k = product_pair[0];
    return refmap[k] != null;
}

function fixPair(product_pair) {
    var k = product_pair[0];
    var v = product_pair[1];
    return [refmap[k], v];
}

function trimProduct(full_product) {
    return _.object(_.pairs(full_product)
        .filter(goodPair)
        .map(fixPair));
}

console.log(data.map(trimProduct));

通过这种方式,您可以将整个转换转换为产品阵列上的一个同步map

请注意,这里使用ref的略微简化版本refmap

var refmap = _.object(ref.map(function(r) {
    return [r.name, r.map_to];
}));

// OR

var refmap = {
    'ProductId': 'item_id',
    'ProductName': 'item_name',
    'Description': 'description',
};

答案 2 :(得分:1)

我会使用map()transform()

_.map(data, function(item) {
    return _.transform(ref, function(result, r) {
        result[r.map_to] = item[r.name];
    }, {});
});

您正在将data映射到新结构。每个新项都是转换ref项的结果。新对象中的map_to键获取原始集合中的name值。