在Json文件中查找和替换项目

时间:2022-08-29 16:49:17

I'm trying to update items stored in a JSON file in a Express App. Basically I'm reading the contents of the JSON file updating the item fetched by Id and writing to the file the updated item.Problem? It's appending the updated item so I get a duplicated. I can't see where is the error?

我正在尝试更新存储在Express App中的JSON文件中的项目。基本上我正在读取JSON文件的内容,更新Id提取的项目并将更新的项目写入文件。问题?它附加了更新的项目,因此我得到了重复。我看不出错误在哪里?

posts.json:

posts.json:

[
    {
        "name": "first name",
        "description": "test first description",
        "slug": "first-name",
        "id": "2f065d59"
    },
   {
        "name": "second name",
        "description": "test second description",
        "slug": "second-name",
        "id": "0071b034"
    }
]

create-update-delete.js:

创建,更新delete.js:

var express = require('express');
var Creatordb = require('./database/posts.json');
var fs = require('fs');
var uuid = require('node-uuid');
var _ = require('lodash');

 //Create The Item           
var add = function (item) {
  var id = uuid.v4();
  item.id = id;
  Creatordb[item.id] = item;
  var outputFilename = './database/posts.json'; 

  function appendObject(obj){
    var configFile = fs.readFileSync(outputFilename);          
    var config = JSON.parse(configFile); 

    config.push(obj);           

    var configJSON = JSON.stringify(config, null, 4);

    fs.writeFileSync(outputFilename, configJSON);

  }
  appendObject(item);
};

//Get The Item by Id
var getById = function (id) {
  for(var i=0;i<Creatordb.length;i++) {
    var id = Creatordb[i].id;
  }
  return id;
};

//Update The Item 
var update = function (item) {        
  var outputFilename = './database/posts.json'; 
  var configFile = fs.readFileSync(outputFilename);

  var config = JSON.parse(configFile); 


  //using lodash??
 var index = _.indexOf(config, _.find(config, item));

 config.splice(index, 1, item);

  var configJSON = JSON.stringify(config, null, 4);

  fs.writeFileSync(outputFilename, configJSON);

};

If I update an item the posts.json will look like this:

如果我更新一个项目,posts.json将如下所示:

 [
        {
            "name": "first name",
            "description": "test first description",
            "slug": "first-name",
            "id": "2f065d59"
        },

        {
            "name": "second name edited",
            "description": "test second description edited",
            "slug": "second-name-edited",
            //this id disappeared "id": "0071b034"//
        }
    ]

Now with lodash the Id in the updated item is gone away? Can anyone explain? - Thanks

现在有了lodash,更新后的项目中的ID消失了吗?谁有人解释一下? - 谢谢

2 个解决方案

#1


2  

There is two problems:

有两个问题:

  1. You use push what is insert a new item into your list, this is the reason of the 'duplication'

    你使用推送什么是在你的列表中插入一个新项目,这就是'重复'的原因

  2. config[item.id] = item; is not a valid reference. Your config is not like this:

    config [item.id] = item;不是有效的参考。你的配置不是这样的:

    ["0071b034": { name: "Foo"}]

    [“0071b034”:{name:“Foo”}]

So the keys in config are 0,1,2 and not the item.id

所以config中的键是0,1,2而不是item.id

I suggest to use lodash. There are a lots of useful functions, but if you stick this implementation, use this:

我建议用lodash。有很多有用的功能,但是如果你坚持这个实现,请使用:

function findIndex(collection, id) {
  for(var i=0; i<collection.length; i++) {
    if (collection[i].id === id) {
      return i;
    }
  }
}

// In your update function
var index = findIndex(config, item.id);
config[index] = item;

#2


0  

I don't understand, why do you use splice function in the update? In JavaScript, when you deal with objects or arrays, you work with their references, not copies. So, you can replace splice with this one:

我不明白,你为什么在更新中使用拼接功能?在JavaScript中,当您处理对象或数组时,您使用它们的引用,而不是副本。所以,你可以用这个替换拼接:

var obj = _.find(config, ['id', item.id]);
_.assign(obj, item);

In this case, you don't care, if item has all necessary fields, since assign method will update only those fields, that were specified.

在这种情况下,如果item具有所有必需的字段,则您无需关心,因为assign方法将仅更新指定的那些字段。

At the same time, if you 100% sure that new item will always have all fields specified, then Festo's solution is better, since it just replaces a reference of the old item on the new one, which is much faster.

同时,如果您100%确定新项目将始终指定所有字段,那么Festo的解决方案更好,因为它只是替换新项目上旧项目的引用,这要快得多。

var config = [
    {
        "name": "first name",
        "description": "test first description",
        "slug": "first-name",
        "id": "2f065d59"
    },
   {
        "name": "second name",
        "description": "test second description",
        "slug": "second-name",
        "id": "0071b034"
    }
];

function update(item) {
  // Your read file logic.
  
  var obj = _.find(config, ['id', item.id]);
  _.assign(obj, item);
  
  // Your write file logic.
}

console.log('config befor update:', config);
update({  
  "name": "third name",
  "id": "0071b034"
});
console.log('config after update:', config);
<script src="https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js"></script>

#1


2  

There is two problems:

有两个问题:

  1. You use push what is insert a new item into your list, this is the reason of the 'duplication'

    你使用推送什么是在你的列表中插入一个新项目,这就是'重复'的原因

  2. config[item.id] = item; is not a valid reference. Your config is not like this:

    config [item.id] = item;不是有效的参考。你的配置不是这样的:

    ["0071b034": { name: "Foo"}]

    [“0071b034”:{name:“Foo”}]

So the keys in config are 0,1,2 and not the item.id

所以config中的键是0,1,2而不是item.id

I suggest to use lodash. There are a lots of useful functions, but if you stick this implementation, use this:

我建议用lodash。有很多有用的功能,但是如果你坚持这个实现,请使用:

function findIndex(collection, id) {
  for(var i=0; i<collection.length; i++) {
    if (collection[i].id === id) {
      return i;
    }
  }
}

// In your update function
var index = findIndex(config, item.id);
config[index] = item;

#2


0  

I don't understand, why do you use splice function in the update? In JavaScript, when you deal with objects or arrays, you work with their references, not copies. So, you can replace splice with this one:

我不明白,你为什么在更新中使用拼接功能?在JavaScript中,当您处理对象或数组时,您使用它们的引用,而不是副本。所以,你可以用这个替换拼接:

var obj = _.find(config, ['id', item.id]);
_.assign(obj, item);

In this case, you don't care, if item has all necessary fields, since assign method will update only those fields, that were specified.

在这种情况下,如果item具有所有必需的字段,则您无需关心,因为assign方法将仅更新指定的那些字段。

At the same time, if you 100% sure that new item will always have all fields specified, then Festo's solution is better, since it just replaces a reference of the old item on the new one, which is much faster.

同时,如果您100%确定新项目将始终指定所有字段,那么Festo的解决方案更好,因为它只是替换新项目上旧项目的引用,这要快得多。

var config = [
    {
        "name": "first name",
        "description": "test first description",
        "slug": "first-name",
        "id": "2f065d59"
    },
   {
        "name": "second name",
        "description": "test second description",
        "slug": "second-name",
        "id": "0071b034"
    }
];

function update(item) {
  // Your read file logic.
  
  var obj = _.find(config, ['id', item.id]);
  _.assign(obj, item);
  
  // Your write file logic.
}

console.log('config befor update:', config);
update({  
  "name": "third name",
  "id": "0071b034"
});
console.log('config after update:', config);
<script src="https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js"></script>

相关文章